如何在 Laravel / React 中使用 Microsoft GRAPH 验证我的用户

问题描述 投票:0回答:1

我需要使用 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

reactjs laravel cors microsoft-graph-api
1个回答
0
投票

¿你找到解决问题的方法了吗?

© www.soinside.com 2019 - 2024. All rights reserved.