AuthSession Silent Authentication

Please provide the following:

  1. SDK Version: 45
  2. Platforms: Android 11

I am trying to implemnt an example expo app with react navigation, mobx and authentication. I am using expo’s AuthSession to do the authentication. I start the application on my phone using expo start. However, every time I start the application I have to log in again. How can I prevent this from happening. Am I doing something wrong or is it because the app is running inside Expo Go?
Code:
My mobx store for sharing the user info and controling authentication. ClientId and auth domain have been removed:

import { action, computed, makeObservable, observable } from "mobx";
import React from "react";
import * as AuthSession from "expo-auth-session";
import { Platform } from "react-native";
import jwtDecode, { JwtPayload } from "jwt-decode";
import { openAuthSessionAsync } from "expo-web-browser";

export class UserStore {

    auth0ClientId = "clientId";
    authorizationEndpoint = "endpoint";
    discoveryDoc: AuthSession.DiscoveryDocument = { authorizationEndpoint: this.authorizationEndpoint };
    useProxy: boolean = false;
    request: AuthSession.AuthRequest | null = null;
    userName: string | null = null;
    constructor() {
        this.useProxy = Platform.select({ web: false, default: false });
        makeObservable(this, {
            preperaLogInRequest: action.bound,
            logIn: action.bound,
            userName: observable,
            isLoading: computed,
            logOut: action.bound
        });
    }

    get isLoading() {
        return this.request === null;
    }

    async preperaLogInRequest() {
        let redirectUri = AuthSession.makeRedirectUri({ useProxy: this.useProxy });
        let tmp = await AuthSession.startAsync({authUrl: this.authorizationEndpoint, returnUrl: redirectUri});
        console.log("tmp is: " + JSON.stringify(tmp));
        
        this.request = await AuthSession.loadAsync({
            redirectUri,
            clientId: this.auth0ClientId,
            responseType: "id_token",
            prompt: AuthSession.Prompt.Login,
            scopes: ["openid", "profile"],
            extraParams: {
                nonce: "nonce",
            },
        }, this.discoveryDoc);
    }

    async logIn() {
        if (this.request) {
            let result = await this.request.promptAsync(this.discoveryDoc, { useProxy: this.useProxy });
            if (result) {
                if (result.type === "error") {
                    console.log(
                        "Authentication error: " +
                        (result.params.error_description || "something went wrong")
                    );
                    return;
                }
                if (result.type === "success") {
                    console.log("success");
                    const jwtToken = result.params.id_token;
                    const decoded = jwtDecode<JwtPayload & { name: string }>(jwtToken);
                    const { name } = decoded;
                    this.userName = name;
                }
            }
            else {
                console.log("Something went wrong during log in");
            }
        }
    }

    async logOut() {
        try {
            let res = await openAuthSessionAsync(`https://dev-j3dkt6a3.us.auth0.com/logout?client_id=1wMZHHb2znirLmNv1GHlqDKz5JT9FN7d`, 'redirectUrl');
            console.log(JSON.stringify(res))
            this.userName = null;
        }
        catch (error) {
            console.log("Failed to log out: " + error);
        }
    }
}

const userStore = new UserStore();
export const UserStoreContext = React.createContext(userStore);
export const useUserStore = () => React.useContext(UserStoreContext)

My index.tsx:

/**
 * If you are not familiar with React Navigation, refer to the "Fundamentals" guide:
 * https://reactnavigation.org/docs/getting-started
 *
 */
import { FontAwesome } from '@expo/vector-icons';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { NavigationContainer, DefaultTheme, DarkTheme } from '@react-navigation/native';
import { createNativeStackNavigator, NativeStackScreenProps } from '@react-navigation/native-stack';
import * as React from 'react';
import { ColorSchemeName, Pressable, Platform, Alert, View, Button, StyleSheet, Text } from 'react-native';

import * as AuthSession from "expo-auth-session";
import jwtDecode from "jwt-decode";
import { useState, useEffect } from "react";
import Colors from '../constants/Colors';
import useColorScheme from '../hooks/useColorScheme';
import ModalScreen from '../screens/ModalScreen';
import NotFoundScreen from '../screens/NotFoundScreen';
import TabOneScreen from '../screens/TabOneScreen';
import TabTwoScreen from '../screens/TabTwoScreen';
import { RootStackParamList, RootTabParamList, RootTabScreenProps } from '../types';
import LinkingConfiguration from './LinkingConfiguration';
import { useUserStore } from '../store/UserStore';
import { observer } from 'mobx-react-lite';

export default function Navigation({ colorScheme }: { colorScheme: ColorSchemeName }) {
  return (
    <NavigationContainer
      linking={LinkingConfiguration}
      theme={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
      <RootNavigator />
    </NavigationContainer>
  );
}



const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center",
  },
  title: {
    fontSize: 20,
    textAlign: "center",
    marginTop: 40,
  },
});

function LogIn() {
  const { logIn } = useUserStore();
  return (
    <View style={styles.container}>
      <Button
        title="Log in with Auth0"
        onPress={() => logIn()}
      />
    </View>
  );
}

const Stack = createNativeStackNavigator<RootStackParamList>();

const RootNavigator = observer(() => {
  const { userName, isLoading, preperaLogInRequest } = useUserStore();
  
  useEffect(()=>{preperaLogInRequest()}, []);

  return (
    <>
    {
      isLoading?
      <Stack.Navigator>
      {userName ?
        <>
          <Stack.Screen name="Root" component={BottomTabNavigator} options={{ headerShown: false }} />
          <Stack.Screen name="NotFound" component={NotFoundScreen} options={{ title: 'Oops!' }} />
          <Stack.Group screenOptions={{ presentation: 'modal' }}>
            <Stack.Screen name="Modal" component={ModalScreen} />
          </Stack.Group>
        </> :
        <>
          <Stack.Screen name="LogIn" component={LogIn} options={{ headerShown: false }} />
        </>
      }
    </Stack.Navigator>:
    <Text>Loading</Text>
    }
    </>
  );
})

/**
 * A bottom tab navigator displays tab buttons on the bottom of the display to switch screens.
 * https://reactnavigation.org/docs/bottom-tab-navigator
 */
const BottomTab = createBottomTabNavigator<RootTabParamList>();

function BottomTabNavigator() {
  const colorScheme = useColorScheme();

  return (
    <BottomTab.Navigator
      initialRouteName="TabOne"
      screenOptions={{
        tabBarActiveTintColor: Colors[colorScheme].tint,
      }}>
      <BottomTab.Screen
        name="TabOne"
        component={TabOneScreen}
        options={({ navigation }: RootTabScreenProps<'TabOne'>) => ({
          title: 'Tab One',
          tabBarIcon: ({ color }) => <TabBarIcon name="code" color={color} />,
          headerRight: () => (
            <Pressable
              onPress={() => navigation.navigate('Modal')}
              style={({ pressed }) => ({
                opacity: pressed ? 0.5 : 1,
              })}>
              <FontAwesome
                name="info-circle"
                size={25}
                color={Colors[colorScheme].text}
                style={{ marginRight: 15 }}
              />
            </Pressable>
          ),
        })}
      />
      <BottomTab.Screen
        name="TabTwo"
        component={TabTwoScreen}
        options={{
          title: 'Tab Two',
          tabBarIcon: ({ color }) => <TabBarIcon name="code" color={color} />,
        }}
      />
    </BottomTab.Navigator>
  );
}

/**
 * You can explore the built-in icon families and icons on the web at https://icons.expo.fyi/
 */
function TabBarIcon(props: {
  name: React.ComponentProps<typeof FontAwesome>['name'];
  color: string;
}) {
  return <FontAwesome size={30} style={{ marginBottom: -3 }} {...props} />;
}

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.