From 9fbb74ba60b8e5262e79e2c4d421b14ce9e9eed8 Mon Sep 17 00:00:00 2001 From: smanylov Date: Wed, 11 Mar 2026 18:21:19 +0700 Subject: [PATCH] add new yandex auth --- src/app/[locale]/login/callback/page.tsx | 53 +++++++++++++++++++++++ src/app/[locale]/login/page.tsx | 3 +- src/app/actions/yandexAuth.ts | 1 - src/app/api/auth/yandex/callback/route.ts | 38 ++++++++++++++++ src/app/components/YandexLogin.tsx | 29 +++++-------- src/app/components/YandexLoginButton.tsx | 15 +++++++ src/app/styles/global-styles.scss | 26 +++++++++++ src/app/styles/pages-styles.scss | 11 +++++ 8 files changed, 156 insertions(+), 20 deletions(-) create mode 100644 src/app/[locale]/login/callback/page.tsx create mode 100644 src/app/api/auth/yandex/callback/route.ts create mode 100644 src/app/components/YandexLoginButton.tsx diff --git a/src/app/[locale]/login/callback/page.tsx b/src/app/[locale]/login/callback/page.tsx new file mode 100644 index 0000000..50bba10 --- /dev/null +++ b/src/app/[locale]/login/callback/page.tsx @@ -0,0 +1,53 @@ +'use client' + +import { useEffect } from 'react'; +import { useSearchParams, useRouter } from 'next/navigation'; +import styles from '@/app/styles/module/login.module.scss' + +export default function YandexCallback() { + const searchParams = useSearchParams(); + const router = useRouter(); + + useEffect(() => { + const code = searchParams.get('code'); + const error = searchParams.get('error'); + + if (error) { + console.error('Ошибка авторизации:', error); + router.push('/login?error=yandex_denied'); + return; + } + + if (code) { + console.log('получаю код'); + console.log(code); + fetch('/api/auth/yandex/callback', { + method: 'POST', + body: JSON.stringify({ code }) + }) + .then(res => res.json()) + .then(data => { + if (data.success) { + console.log(data); + console.log('all ok'); + /* router.push('/dashboard'); */ + } + }); + } + }, [searchParams, router]); + + return ( +
+
+
+
+
+
+ ) +} \ No newline at end of file diff --git a/src/app/[locale]/login/page.tsx b/src/app/[locale]/login/page.tsx index 423d00c..f9552ff 100644 --- a/src/app/[locale]/login/page.tsx +++ b/src/app/[locale]/login/page.tsx @@ -9,6 +9,7 @@ import VKLogin from '@/app/components/VKLogin'; import YandexAuthWithScript from '@/app/components/YandexLogin'; import { getHealt } from '@/app/actions/action'; import { Suspense } from 'react'; +import {YandexLoginButton} from '@/app/components/YandexLoginButton'; export const metadata: Metadata = { title: 'Login', @@ -51,7 +52,7 @@ export default function Page() {
- +

{t('no-account')}? diff --git a/src/app/actions/yandexAuth.ts b/src/app/actions/yandexAuth.ts index 0623101..4397a57 100644 --- a/src/app/actions/yandexAuth.ts +++ b/src/app/actions/yandexAuth.ts @@ -4,7 +4,6 @@ import { API_BASE_URL } from '@/app/actions/definitions'; import { createSession } from '@/app/actions/session'; import { redirect } from 'next/navigation'; - export async function YandexAuthorization(data: any, codeVerifier: string) { console.log(data); diff --git a/src/app/api/auth/yandex/callback/route.ts b/src/app/api/auth/yandex/callback/route.ts new file mode 100644 index 0000000..7daf57b --- /dev/null +++ b/src/app/api/auth/yandex/callback/route.ts @@ -0,0 +1,38 @@ +import { NextResponse } from 'next/server'; + +export async function POST(request: Request) { + const { code } = await request.json(); + + try { + const response = await fetch('https://oauth.yandex.ru/token', { + method: 'POST', + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + body: new URLSearchParams({ + grant_type: 'authorization_code', + code, + client_id: 'b356a7ceac0f4c50a3b434220f86bce0', + client_secret: '0800f7774f7d4e19ad4b434f10afd4ab', + }) + }); + + const data = await response.json(); + + console.log(data); + + if (data.access_token) { + const userInfo = await fetch('https://login.yandex.ru/info?format=json', { + headers: { 'Authorization': `OAuth ${data.access_token}` } + }).then(r => r.json()); + + console.log(userInfo); + + // Тут мне нужно будет отправить сделать запрос в бек с userInfo и там уже редиректить на дешборд + + return NextResponse.json({ success: true }); + } + } catch (error) { + console.error('Token exchange failed:', error); + } + + return NextResponse.json({ success: false }, { status: 400 }); +} \ No newline at end of file diff --git a/src/app/components/YandexLogin.tsx b/src/app/components/YandexLogin.tsx index 1dc7fd0..90abb70 100644 --- a/src/app/components/YandexLogin.tsx +++ b/src/app/components/YandexLogin.tsx @@ -14,10 +14,6 @@ export default function YandexAuthWithScript() { const [isReady, setIsReady] = useState(false); const [showButton, setShowButton] = useState(true); - const handleLogin = (token: string) => { - console.log('handleLogin'); - }; - useEffect(() => { if (!isReady || !buttonRef.current || !window.YaAuthSuggest) return; @@ -25,31 +21,28 @@ export default function YandexAuthWithScript() { { client_id: 'b356a7ceac0f4c50a3b434220f86bce0', response_type: 'token', - redirect_uri: `http://localhost:2999/ru/login`, + redirect_uri: `https://fallibly-desired-moonfish.cloudpub.ru/en/login`, }, - 'http://localhost:2999', + 'https://fallibly-desired-moonfish.cloudpub.ru', { parentId: buttonRef.current.id, view: 'button', buttonView: 'main', buttonTheme: 'light', - buttonSize: 'm', + buttonSize: 'l', buttonBorderRadius: 10 } ) - .then((result: any) => { - console.log('then'); + .then(function (result: any) { + console.log('you at least try?') console.log(result); - if (result?.access_token) { - handleLogin(result.access_token); - } else { - setTimeout(() => { - setShowButton(false); - }, 1000) - } + return result.handler(); }) - .catch((error: any) => { - console.error('Yandex auth error:', error); + .then(function (data: any) { + console.log('Сообщение с токеном: ', data); + }) + .catch(function (error: any) { + console.log('Что-то пошло не так: ', error); }); }, [isReady]); diff --git a/src/app/components/YandexLoginButton.tsx b/src/app/components/YandexLoginButton.tsx new file mode 100644 index 0000000..5e23a40 --- /dev/null +++ b/src/app/components/YandexLoginButton.tsx @@ -0,0 +1,15 @@ +export function YandexLoginButton() { + const clientId = 'b356a7ceac0f4c50a3b434220f86bce0'; + const redirectUri = encodeURIComponent('https://fallibly-desired-moonfish.cloudpub.ru/login/callback'); + + const authUrl = `https://oauth.yandex.ru/authorize?response_type=code&client_id=${clientId}&redirect_uri=${redirectUri}&force_confirm=yes`; + + return ( + + Войти через Яндекс + + ); +} \ No newline at end of file diff --git a/src/app/styles/global-styles.scss b/src/app/styles/global-styles.scss index 3114f9b..3aa4a83 100644 --- a/src/app/styles/global-styles.scss +++ b/src/app/styles/global-styles.scss @@ -710,4 +710,30 @@ color: #dc2626; font-weight: 500; } +} + +.yandex-auth-button { + display: flex; + align-items: center; + justify-content: center; + gap: 10px; + padding: 14px 24px; + border: none; + border-radius: 8px; + font-size: 16px; + font-weight: 500; + cursor: pointer; + transition: all 0.2s ease; + text-decoration: none; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); + width: 100%; + box-sizing: border-box; + background: #000000; + color: #FFFFFF; + + &:hover { + background: #1a1a1a; + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25); + /* transform: translateY(-2px); */ + } } \ No newline at end of file diff --git a/src/app/styles/pages-styles.scss b/src/app/styles/pages-styles.scss index e8084c1..eb4a00b 100644 --- a/src/app/styles/pages-styles.scss +++ b/src/app/styles/pages-styles.scss @@ -3983,6 +3983,17 @@ border-radius: 50%; animation: spin 1s linear infinite; } + + &.large { + width: 80px; + height: 80px; + + &::before { + border: 10px solid #e5e7eb; + border-top: 10px solid #667eea; + } + } + } }