我需要使用 Microsoft GRAPH 进行身份验证。
Laravel 框架:9.46.0 反应:^18.2.0
登录和回调函数是在服务器端用laravel完成的。 调用这些函数并存储用户数据应该在客户端使用 REACT 完成。
我想到了执行登录功能,然后重新转发登录链接。但是,在哪里调用我的回调呢?
此外,当我尝试将用户重定向到登录链接时,我收到 CORS 错误。
这是我的服务器端:
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Carbon\Carbon;
use App\Models\User;
use Microsoft\Graph\Graph;
use Microsoft\Graph\Model;
use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
use League\OAuth2\Client\Provider\GenericProvider;
class AuthController extends Controller
{
//SIGN IN
public function signin()
{
// Initialize the OAuth client
$oauthClient = new GenericProvider([
'clientId' => env('OAUTH_APP_ID'),
'clientSecret' => env('OAUTH_APP_PASSWORD'),
'redirectUri' => env('OAUTH_REDIRECT_URI'),
'urlAuthorize' => env('OAUTH_AUTHORITY') . env('OAUTH_AUTHORIZE_ENDPOINT'),
'urlAccessToken' => env('OAUTH_AUTHORITY') . env('OAUTH_TOKEN_ENDPOINT'),
'urlResourceOwnerDetails' => '',
'scopes' => env('OAUTH_SCOPES')
]);
$authUrl = $oauthClient->getAuthorizationUrl();
// Save client state so we can validate in callback
session(['oauthState' => $oauthClient->getState()]);
// Redirect to AAD signin page
return redirect()->away($authUrl);
}
//CALL BACK
public function callback(Request $request)
{
// Validate state
$expectedState = session('oauthState');
$request->session()->forget('oauthState');
$providedState = $request->query('state');
if (!isset($expectedState)) {
// If there is no expected state in the session,
// do nothing and redirect to the home page.
return redirect('/');
}
if (!isset($providedState) || $expectedState != $providedState) {
return redirect('/')
->with('error', 'Invalid auth state')
->with('errorDetail', 'The provided auth state did not match the expected value');
}
// Authorization code should be in the "code" query param
$authCode = $request->query('code');
if (isset($authCode)) {
// Initialize the OAuth client
$oauthClient = new \League\OAuth2\Client\Provider\GenericProvider([
'clientId' => env('OAUTH_APP_ID'),
'clientSecret' => env('OAUTH_APP_PASSWORD'),
'redirectUri' => env('OAUTH_REDIRECT_URI'),
'urlAuthorize' => env('OAUTH_AUTHORITY') . env('OAUTH_AUTHORIZE_ENDPOINT'),
'urlAccessToken' => env('OAUTH_AUTHORITY') . env('OAUTH_TOKEN_ENDPOINT'),
'urlResourceOwnerDetails' => '',
'scopes' => env('OAUTH_SCOPES')
]);
try {
// Make the token request
$accessToken = $oauthClient->getAccessToken('authorization_code', [
'code' => $authCode
]);
$graph = new Graph();
$graph->setAccessToken($accessToken->getToken());
$user_ms = $graph->createRequest('GET', '/me?$select=displayName,mail,userPrincipalName')
->setReturnType(Model\User::class)
->execute();
$photo_path = public_path() . '/assets/img/avatars/' . md5($user_ms->getUserPrincipalName()) . '.jpg';
if (!file_exists($photo_path)) {
try {
$photo = $graph->createRequest("GET", "/me/photo/\$value")->download($photo_path);
}
catch (ClientException $e) {
unlink($photo_path);
}
}
if ($user = User::select('id')->where('username', $user_ms->getUserPrincipalName())->first()) {
$u = $user;
}
else {
$u = new User();
$u->email = $user_ms->getMail();
$u->username = $user_ms->getUserPrincipalName();
$u->displayName = $user_ms->getDisplayName();
}
$u->last_login_at = Carbon::now()->toDateTimeString();
$u->save();
Auth::loginUsingId($u->id);
}
catch (League\OAuth2\Client\Provider\Exception\IdentityProviderException $e) {
return redirect('/')
->with('error', 'Error requesting access token')
->with('errorDetail', $e->getMessage());
}
}
return redirect()->intended('/')
->with('error', $request->query('error'))
->with('errorDetail', $request->query('error_description'));
}
我的 CORS 配置:
<?php
return [
'paths' => ['api/*'],
'allowed_methods' => ['*'],
'allowed_origins' => ['http://localhost:3000'],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => false,
];
我的登录组件在反应中
import React from 'react';
import { Button } from 'react-bootstrap';
import { Box } from '@mui/material';
import axios from 'axios';
function LoginButton() {
const handleLogin = async () => {
try {
const response = await axios.get(
`${process.env.REACT_APP_API_URL2}api/login`
);
// Redirect to the Microsoft Graph login page
window.location.href = response.data;
} catch (err) {
console.log(err);
}
};
return (
<Box textAlign="center" alignSelf="center">
<Button
size="large"
color="buttonBlue"
variant="outlined"
className="ml-auto login_button buttonYellow button"
onClick={handleLogin}
>
Se connecter
</Button>
</Box>
);
}
export default LoginButton;
我已经尝试过让 microsoft graph 登录 100% 反应并且它正在工作。我也在 Laravel 中进行了 100% 的尝试,它也能正常工作,但现在,我不知道如何链接 React 和 Laravel。
当我尝试重定向到response.data中的链接时出现cors错误:
"myLink" redirected from 'http://127.0.0.1:8000/api/login') from origin 'http://localhost:3000' has been blocked by CORS policy
¿你找到解决问题的方法了吗?