通过 Azure AD OAuth 登录获取用户数据 - React Native Expo App

Getting user data through an Azure AD OAuth login - React Native Expo App

在我的应用程序中,我使用 useAuthRequest 通过 Microsoft Azure AD 登录 对用户进行身份验证,正如 Expo Documentation 所建议的那样(此登录方法成功运行)。在我的请求中,我在范围 ['openid', 'profile', 'email'].

中解析

我想在我的应用程序中显示用户名和电子邮件等数据,但不知道如何获取这些数据。

经过一些研究,我发现这个数据保存在一个JWT format的Token中,并且可以使用简单的JWT解码器包对其进行解码。

问题是我不知道如何或从哪里获得特定的令牌来对其进行解码。

这是我的代码的摘录:

const discovery = useAutoDiscovery(`${config.ENDPOINT_URL}`);

    const [request, response, promptAsync] = useAuthRequest(
      {
        clientId: `${config.CLIENT_ID}`,
        clientSecret: `${config.CLIENT_SECRET}`,
        scopes: [ 'openid', 'profile', 'email'],
        prompt: 'login',
        redirectUri: "msauth.*MyBundleId*://auth",
        returnUrl: "msauth.*MyBundleId*://auth",
      },
        discovery,
        console.log(discovery)
      );

我认为值得一提的console.log(discovery) returns两个具体的link:

"token_endpoint": "https://login.microsoftonline.com/*MyAppsTenantId*/oauth2/v2.0/token",

和:

"userinfo_endpoint": "https://graph.microsoft.com/oidc/userinfo"

在我的浏览器中输入 token_endpoint 时,显示一条错误消息

AADSTS900561: The endpoint only accepts POST, OPTIONS requests. Received a GET request.

并且在我的浏览器上输入 userinfo_endpoint link 时,它 returns 一个包含以下数据的散列:

{"error":{"code":"InvalidAuthenticationToken","message":"Access token is empty.","innerError":{"date":"2022-04-28T13:00:07","request-id":"*MyAppTenantId","client-request-id":"*ClientRequestId*"}}}

有用link秒:

-Microsoft UserInfo

-OpenID Scopes

-Active Directory Protocols

如果您对如何获取包含用户数据的 JWT 令牌有任何线索、提示或信息,请在下方分享,我将非常乐意阅读和发表评论。

请检查参考文献是否可以解决:

首先错误AADSTS900561可能是因为

  • 浏览器上的第 3 方 cookie。为避免这种情况 >打开 cookie 设置 >取消选择 “阻止 third-party cookies”,清除你的 cookies。
  • 或者是权限问题url,请检查是否是 正确。
  • 根据Microsoft docs :The error AADSTS900561

To redeem the code for an access token, the app should send a POST request to the /token endpoint. Also, prior to this, you should provide an authorization code and send it in the POST request to the /token endpoint.


关于获取token和解码,找不到参考文献,请检查他们是否可以帮助或提供继续进行的线索。

取自 React Native on Expo- Stack Overflow reference

const discovery = useAutoDiscovery('https://login.microsoftonline.com/TENANT_ID/v2.0');
  // Request
  const [request, response, promptAsync] = useAuthRequest(
    {
      clientId: 'YOUR - CLIENT - ID',
      scopes: ['openid', 'profile', 'email', 'offline_access' 'user.read
],
      redirectUri: makeRedirectUri({
        scheme: 'exp://YOUR IP ADDRESS:19000'
        }),
grant_type: ‘authorization_code’,

        // codeChallenge: 'CODE_CHALLENGE',
        // codeChallengeMethod: 'S256',
        // usePKCE: true
      },
    discovery
  );

  React.useEffect(() => {
    if (response && 'params' in response) {
        if (response.params && 'code' in response.params) {

            (async function getToken() {
                console.log('-----------------------')
                console.log(response.params.code)
                console.log('-----------------------')

                try {
                    // @ts-ignore
                    const { accessToken } = await exchangeCodeAsync({
                        code: response.params.code,
                        clientId: 'CLIENT - ID',
                        redirectUri: makeRedirectUri({
                          scheme: ' '
                          }),
                        scopes: ['openid', 'profile', 'email', 'offline_access'],
                        grant_type: "authorization_code",
                        extraParams: {
                          // code_verifier: "CODE_VERIFIER",
                          code_verifier: request?.codeVerifier || '' ,
                      },
                    }, {
                        tokenEndpoint: 'https://login.microsoftonline.com/TENNANT_ID/oauth2/v2.0/token' // 
                    })

             
                    console.log(accessToken)

请检查每个参考资料:

  1. expo-react-native-azure-ad-2| GitHub
  2. 同时勾选
  3. 看看这个 github discussion on expo issues 是否可以提供获取用户令牌的想法。

解码:

   decodeJwtToken(token) {
   console.log("Entered decodeJwtToken function") 
   var temp = token.replace(/-/i, "+");
   var newtoken = temp.replace(/_/i, "/"); 
   var parsedObj = JSON.parse(new Buffer(newtoken.split(".")[1], "base64").toString()) 
   console.log(parsedObj) } 

检查是否可以从令牌中提取用户以进行解析>JSON.stringify(user)。 参见 Decoding JWT token - SO

&npm:expo-react-native-azure-ad-2 | Skypack

如果其他声明需要,您可以在应用程序令牌配置中配置可选声明:


以防万一如果使用react native azure auth,下面的代码可以提供用户信息:

try {
      let tokens = await azureAuth.webAuth.authorize({scope: 'openid profile User.Read Mail.Read' })
      this.setState({ accessToken: tokens.accessToken });
      let info = await azureAuth.auth.msGraphRequest({token: tokens.accessToken, path: '/me'})
      this.setState({ user: info.displayName, userId: tokens.userId })
    } catch (error) {
      console.log(error)
    }
                    

我终于解决了这个问题!

我找到了一个名为 azure-ad-graph-expo 的库,它以非常简单的方式完成了我想做的事情 -> 不需要 API 调用和解析访问令牌。

这是我的代码的摘录:

  const [resultData, setResultData] = useState({});

  const _handlePressAsync = async () => {
    let result = await openAuthSession(azureAdAppProps);
    setResultData({ result });
  }

  const azureAdAppProps = {
    clientId        :   `******************`,
    tenantId        :   `******************`,
    scope           :   'user.read',
    redirectUrl     :   AuthSession.makeRedirectUri({ path: "auth"}),
    returnUrl       :   "mybundleid://auth",
    clientSecret    :   `******************`,
    domainHint      :   'login.microsoftonline.com',
    prompt          :   'login'
};

您必须在 Azure 门户中设置重定向 Url。

此代码成功运行,因为它是在应用构建本身而不是 Expo Go 应用中测试的:

  • => 要创建构建,运行 expo build:iosexpo build:android

  • => 如果您想在 Expo Go 应用程序中对其进行测试,请在 Azure AD 门户上将您的本地主机设置为重定向Url,并将代码设置为redirectUrl: AuthSession.makeRedirectUri()

  • => 对于 bundle id,您可以设置自己的 -> 在 app.json 内创建 "scheme""expo:" 括号内。捆绑 ID 按以下模式编写:com.your-company.app-name.

为了测试我的应用程序是否正在获取用户数据,在登录按钮下方添加了以下代码:

        {resultData ? (
          <Text>{JSON.stringify(resultData)}</Text>
        ) : 
          <Text>Nothing to see here.</Text>}

这是验证后的结果: User Data

如果您对此问题有任何疑问或补充,请随时在下方发表评论! :D 非常感谢此线程中的所有帮助和评论!