Fusion Auth在授权后没有重定向到Expo App的OAuth回调路由。

huangapple go评论72阅读模式
英文:

Fusion Auth is not redirecting to the Expo App oauth callback route after authorization

问题

I am writing an app in Expo. I am using Fusion Auth as an auth server, hosted locally.

I want to use the OAuth authorization flow with PKCE. The app is sending a request to /authorize, then I am getting the code. The auth server should redirect me to the auth callback route. However, Fusion Auth is not redirecting me to the auth callback route but closes the browser modal and keeps the login page active.

I am writing code with Expo Auth Session.

This is my application's Fusion Auth configuration:

Fusion Auth在授权后没有重定向到Expo App的OAuth回调路由。

And this is my login page code in the Expo app:

import * as AuthSession from 'expo-auth-session';
import { Button } from 'react-native';

export default function Login() {
  const discovery = AuthSession.useAutoDiscovery("http://192.168.100.17:9011/.well-known/openid-configuration/a5673e50-cbcc-14ec-5ae3-bde9d60a1950");

  const [request, response, promptAsync] = AuthSession.useAuthRequest({
    clientId: process.env.FUSIONAUTH_CLIENT_ID,
    scopes: ['openid', 'offline_access'],
    redirectUri: AuthSession.makeRedirectUri({
      path: 'oauth', // route in "app" folder in Expo router
      scheme: 'myapp', // in app.json scheme is "myapp" too
    }),
  }, discovery);

  return <Button title="Login" onPress={() => promptAsync()} />
}

This is how my app currently behaves:

Fusion Auth在授权后没有重定向到Expo App的OAuth回调路由。

This is the request object result:

{
  "clientId": "7ae2dde8-5710-4f6f-b159-693a394e8eee",
  "clientSecret": undefined,
  "codeChallenge": "iPLWzzLvGhYvaCRbwb6-aBLdiOE8jLPEdLWWP91Xc8Q",
  "codeChallengeMethod": "S256",
  "codeVerifier": "c6RBW8y9mmWrqK0TRXQud7lYlPCsYS8QUQp4LZkKFZVG8ovruNzgMsDPjdGKPPkWv6bsZQtpQtcHQ24Hq0HHBLfhX36aliDIlTMumLtJzwL8Q7UI3M6rPxzv4zYpSbcD",
  "extraParams": {},
  "prompt": undefined,
  "redirectUri": "exp://192.168.100.17:8081/--/oauth",
  "responseType": "code",
  "scopes": ["openid", "offline_access"],
  "state": "PJIpedf69M",
  "url": "http://192.168.100.17:9011/oauth2/authorize?code_challenge=iPLWzzLvGhYvaCRbwb6-aBLdiOE8jLPEdLWWP91Xc8Q&code_challenge_method=S256&redirect_uri=exp%3A%2F%2F192.168.100.17%3A8081%2F--%2Foauth&client_id=7ae2dde8-5710-4f6f-b159-693a394e8eee&response_type=code&state=PJIpedf69M&scope=openid%20offline_access",
  "usePKCE": true
}

This is the response object:

{
  "authentication": null,
  "error": null,
  "errorCode": null,
  "params": {
    "code": "NDyy5uMqvstnap3JIz6GWyYk1Q34ayOjPvyY3lIsayk",
    "locale": "pl_PL",
    "state": "PJIpedf69M",
    "userState": "Authenticated"
  },
  "type": "success",
  "url": "exp://192.168.100.17:8081/--/oauth?code=NDyy5uMqvstnap3JIz6GWyYk1Q34ayOjPvyY3lIsayk&locale=pl_PL&state=PJIpedf69M&userState=Authenticated"
}

Why is Fusion Auth not redirecting me to the redirect URL? Should I build the app using prebuild or something else? Or should I create a development build and use a scheme like myapp://oauth? But then, should I create an Apple Developer account for that?

英文:

I am writing an app in Expo. I am using Fusion Auth as a auth server, hosted locally.

I want to use OAuth auth flow with PKCE, app is sending a request to /authorize, then i am getting the code, auth server should redirect me to auth callback route, this auth callback route should send that code to token endpoint. However, fusion auth is not redirecting me from to auth callback route, but closes browser modal and keeps the login page active.

I am writing code with https://docs.expo.dev/versions/latest/sdk/auth-session/

this is my application Fusion Auth config

Fusion Auth在授权后没有重定向到Expo App的OAuth回调路由。

and this is my login page code in Expo app:

import * as AuthSession from &#39;expo-auth-session&#39;
import { Button } from &#39;react-native&#39;;

export default function Login() {
  const discovery = AuthSession.useAutoDiscovery(&quot;http://192.168.100.17:9011/.well-known/openid-configuration/a5673e50-cbcc-14ec-5ae3-bde9d60a1950&quot;);

  const [request, response, promptAsync] = AuthSession.useAuthRequest({
    clientId: process.env.FUSIONAUTH_CLIENT_ID,
    scopes: [&#39;openid&#39;, &#39;offline_access&#39;],
    redirectUri: AuthSession.makeRedirectUri({
      path: &#39;oauth&#39;, // route in &quot;app&quot; folder in expo router
      scheme: &#39;myapp&#39;, // in app.json scheme is &quot;myapp&quot; too
    }),
  }, discovery);

  return &lt;Button title=&quot;Login&quot; onPress={() =&gt; promptAsync()} /&gt;
} 

this is how my app currently behaves:
Fusion Auth在授权后没有重定向到Expo App的OAuth回调路由。

this is the request object result:

{
  &quot;clientId&quot;: &quot;7ae2dde8-5710-4f6f-b159-693a394e8eee&quot;,
  &quot;clientSecret&quot;: undefined,
  &quot;codeChallenge&quot;: &quot;iPLWzzLvGhYvaCRbwb6-aBLdiOE8jLPEdLWWP91Xc8Q&quot;,
  &quot;codeChallengeMethod&quot;: &quot;S256&quot;,
  &quot;codeVerifier&quot;: &quot;c6RBW8y9mmWrqK0TRXQud7lYlPCsYS8QUQp4LZkKFZVG8ovruNzgMsDPjdGKPPkWv6bsZQtpQtcHQ24Hq0HHBLfhX36aliDIlTMumLtJzwL8Q7UI3M6rPxzv4zYpSbcD&quot;,
  &quot;extraParams&quot;: {},
  &quot;prompt&quot;: undefined,
  &quot;redirectUri&quot;: &quot;exp://192.168.100.17:8081/--/oauth&quot;,
  &quot;responseType&quot;: &quot;code&quot;,
  &quot;scopes&quot;: [&quot;openid&quot;, &quot;offline_access&quot;],
  &quot;state&quot;: &quot;PJIpedf69M&quot;,
  &quot;url&quot;: &quot;http://192.168.100.17:9011/oauth2/authorize?code_challenge=iPLWzzLvGhYvaCRbwb6-aBLdiOE8jLPEdLWWP91Xc8Q&amp;code_challenge_method=S256&amp;redirect_uri=exp%3A%2F%2F192.168.100.17%3A8081%2F--%2Foauth&amp;client_id=7ae2dde8-5710-4f6f-b159-693a394e8eee&amp;response_type=code&amp;state=PJIpedf69M&amp;scope=openid%20offline_access&quot;,
  &quot;usePKCE&quot;: true
}

this is response object:

{
  &quot;authentication&quot;: null,
  &quot;error&quot;: null,
  &quot;errorCode&quot;: null,
  &quot;params&quot;: {
    &quot;code&quot;: &quot;NDyy5uMqvstnap3JIz6GWyYk1Q34ayOjPvyY3lIsayk&quot;,
    &quot;locale&quot;: &quot;pl_PL&quot;,
    &quot;state&quot;: &quot;PJIpedf69M&quot;,
    &quot;userState&quot;: &quot;Authenticated&quot;
  },
  &quot;type&quot;: &quot;success&quot;,
  &quot;url&quot;: &quot;exp://192.168.100.17:8081/--/oauth?code=NDyy5uMqvstnap3JIz6GWyYk1Q34ayOjPvyY3lIsayk&amp;locale=pl_PL&amp;state=PJIpedf69M&amp;userState=Authenticated&quot;
}

Why fusion auth is not redirecting me to redirect url? Should I build app using prebuild or something? Or create a development build and use scheme like myapp://oauth? But then I should create an Apple Developer account for that?

答案1

得分: 0

首先,我不是一个Expo专家,但我成功地使其工作,方法是使用重定向URI的同一页面,而不是/oauth

export default function Login() {
    const [accessToken, setAccessToken] = useState(null);
    const discovery = AuthSession.useAutoDiscovery(urlToFusionAuth);  

    const redirectUri = AuthSession.makeRedirectUri({
        scheme: 'myapp', // 我已经移除了 `path: 'oauth'`
    }); 
    console.log(redirectUri); // 仅为确保在FusionAuth中使用了正确的重定向地址

    const [request, response, promptAsync] = AuthSession.useAuthRequest({
        clientId: process.env.FUSIONAUTH_CLIENT_ID,
        scopes: ['openid', 'offline_access'],
        usePKCE: true, // 你应该使用PKCE
        redirectUri,
    }, discovery);

    // 这在初始登录后我们被重定向回这个页面后被调用
    useEffect(() => {
        if (response) {
            if (response.type === 'success') {
                AuthSession.exchangeCodeAsync({
                    clientId: process.env.FUSIONAUTH_CLIENT_ID,
                    code: response.params.code,
                    extraParams: {
                      code_verifier: request.codeVerifier,
                    },
                    redirectUri,
                }, discovery)
                    .then(setAccessToken)
                    .catch((error) => {
                        console.error(error);
                    });
                return;
            }

            // 你应该在这里处理错误 :)
            console.error(response);
        }
    }, [response]);

    // 有条件地呈现“登录”按钮或检索到的访问令牌
    return (
        {(accessToken)
            ? <Text>{JSON.stringify(accessToken)}</Text>
            : <Button disabled={!request} title="Log in" onPress={() => promptAsync()} />} 
    );
}

在我的示例中,我使用了PKCE,而不是在交换代码以获取访问令牌时需要提供客户端密钥,所以这是我的应用程序设置:

Fusion Auth在授权后没有重定向到Expo App的OAuth回调路由。

英文:

First of all, I'm not an Expo expert, but I was able to make it work by using the same page for the redirect URI instead of /oauth:

export default function Login() {
    const [accessToken, setAccessToken] = useState(null);
    const discovery = AuthSession.useAutoDiscovery(urlToFusionAuth);  

    const redirectUri = AuthSession.makeRedirectUri({
        scheme: &#39;myapp&#39;, // I&#39;ve removed `path: &#39;oauth&#39;`
    }); 
    console.log(redirectUri); // Just to make sure I have the right one in FusionAuth

    const [request, response, promptAsync] = AuthSession.useAuthRequest({
        clientId: process.env.FUSIONAUTH_CLIENT_ID,
        scopes: [&#39;openid&#39;, &#39;offline_access&#39;],
        usePKCE: true, // You should use PKCE
        redirectUri,
    }, discovery);

    // This is being called after we are redirected back to this page after initial login
    useEffect(() =&gt; {
        if (response) {
            if (response.type === &#39;success&#39;) {
                AuthSession.exchangeCodeAsync({
                    clientId: process.env.FUSIONAUTH_CLIENT_ID,
                    code: response.params.code,
                    extraParams: {
                      code_verifier: request.codeVerifier,
                    },
                    redirectUri,
                }, discovery)
                    .then(setAccessToken)
                    .catch((error) =&gt; {
                        console.error(error);
                    });
                return;
            }

            // You should handle errors here :)
            console.error(response);
        }
    }, [response]);

    // Conditionally rendering a &quot;Log in&quot; button or the retrieved access token
    return (
        {(accessToken)
            ? &lt;Text&gt;{JSON.stringify(accessToken)}&lt;/Text&gt;
            : &lt;Button disabled={!request} title=&quot;Log in&quot; onPress={() =&gt; promptAsync()} /&gt;} 
    );
}

In my example, I'm using PKCE instead of having to provide a Client Secret when exchanging the code for an access token, so here's my application settings:

Fusion Auth在授权后没有重定向到Expo App的OAuth回调路由。

huangapple
  • 本文由 发表于 2023年7月10日 17:55:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/76652621.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定