Expo: Using AuthSession unable to open Web Browser for Authentication - react-native

I am using Expo in managed workflow and Expo Go as the debug app (on Android). SDK version is 46. I try to authenticate against an OpenID Connect service (provided by a Keycloak instance). I used the documentation and examples found on the Expo docs but wasn't able to get it running with some weird errors.
Here's my code:
WebBrowser.maybeCompleteAuthSession();
const useProxy = false;
const redirectUri = AuthSession.makeRedirectUri({
useProxy
});
export default function LoginIDPScreen({ navigation }: Props) {
const discovery = AuthSession.useAutoDiscovery('http://192.168.178.131:8080');
// Create and load an auth request
const [request, result, promptAsync] = AuthSession.useAuthRequest({
clientId: 'titan-mobile',
redirectUri,
scopes: ['openid', 'profile', 'email', 'offline_access'],
}, discovery);
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Button title="Login!" disabled={!request} onPress={() => promptAsync({ useProxy }) } />
{result && <Text>{JSON.stringify(result, null, 2)}</Text>}
</View>
);
}
Running this (hitting the "Login" button), it results in the following error:
WARN Possible Unhandled Promise Rejection (id: 0):
Error: Call to function 'ExpoWebBrowser.openBrowserAsync' has been rejected.
→ Caused by: No matching browser activity found
I tried to open a web browser manually using WebBrowser.openBrowserAsync('https://expo.dev') an that works fine, so I guess it's not actually about finding the browser activity.
When I read out the redirectUri it comes out as exp://192.168.178.130:19000, which I found weird as well, but given it can not even open the IDP for authentication, I think this is not the issue.
I intentionally switched off the proxy, afaik the proxy does not work with development envs. Enabling the proxy results in another error:
ERROR Error: Cannot use the AuthSession proxy because the project full name is not defined. Prefer AuthRequest (with the useProxy option set to false) in combination with an Expo Development Client build of your application. To continue using the AuthSession proxy, specify the project full name (#owner/slug) using the projectNameForProxy option.
Adding projectNameForProxy to the arguments for promptAsync() does not work and looking at the documentation for AuthRequest, it strongly recommends not using it and using AuthSession instead..
Any ideas?

Update: found the issue. It was caused by the discovery failing silently. The example code is not well engineered here. There should be a check (even in the example) that detects errors when doing the discovery part.
If you are encountering this, make sure the actual endpoint URL delivered to the auth mechanism is actually set from the discovery.

In My case it was like missing scheme. After adding it worked in expo go
{
"expo": {
"scheme": "your-app-slug"
}
}

Not sure if this will help. I had a similar issue and fixed it by adding intent filters to Expo's app.json config.
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/favicon.png",
"backgroundColor": "#ffffff"
},
"intentFilters": [
{
"autoVerify": true,
"action": "VIEW",
"data": {
"scheme": "msauth",
"host": "com.name.proj"
},
"category": ["BROWSABLE", "DEFAULT"]
}
],
"icon": "./assets/favicon.png",
"package": "com.name.proj",
"permissions": [
"android.permission.ACCESS_COARSE_LOCATION",
"android.permission.ACCESS_FINE_LOCATION",
"android.permission.FOREGROUND_SERVICE",
"android.permission.RECORD_AUDIO"
]
},

Related

Office Word add-in – Msal using login redirect not working on Mac (Safari webkit 1.0)

We’re using Azure B2C to authenticate the users in the Word add-in. The library in Angular (14.1.2) that we use is MSAL which works as expected on Windows.
However, when using it on Mac, the redirect inside the add-in dialog gets stuck and doesn’t go to the Azure B2C page. It writes the cookies and local storage, but never redirects.
angular 14.1.2
azure/msal-angular 2.5.1
azure/msal-browser 2.32.1
Call
this.msalService.loginRedirect().subscribe();
Msal Configuration
`export function msalInstanceFactory(appConfigService: AppConfigService): IPublicClientApplication {
const appConfig = appConfigService.config;
return new PublicClientApplication({
auth: {
clientId: appConfig.aadB2CClientId,
authority: 'https://${appConfig.aadB2CDomain}/${appConfig.aadB2CTenant}/${appConfig.aadB2CSIPolicy}',
redirectUri: appConfig.aadB2CRedirectUri,
postLogoutRedirectUri: getLocationOriginWithPath('logout'),
knownAuthorities: [appConfig.aadB2CDomain],
navigateToLoginRequestUrl: false,
},
cache: {
cacheLocation: BrowserCacheLocation.LocalStorage,
storeAuthStateInCookie: isIE,
},
system: {
loggerOptions: {
loggerCallback: msalLoggerCallback,
logLevel: LogLevel.Verbose,
piiLoggingEnabled: true,
},
},
});
}
export function msalGuardConfigFactory(appConfigService: AppConfigService): MsalGuardConfiguration {
return {
interactionType: InteractionType.Redirect,
authRequest: {
scopes: appConfigService.config.aadB2CConsentScopes,
loginHint: getLoginHint(),
},
};
}`
The funny fact is that if I set a break point just before the execution of the loginRedirect and then press continue it works. So, I tried to set a timeout before that to see if it works but it doesn't.
Also tried to disable ITP security in Safari, but didn't take any effect.

Implementing app tracking transparency permission request on Expo 45

I have a managed-expo (sdk 45) application and for some reason apple rejects my application because they are unable to locate the App Tracking Transparency permission request. I know it has something to do with expo-ads-admob. I am getting this message:
Please explain where we can find the App Tracking Transparency permission request in your app. The request should appear before any data is collected that could be used to track the user.
If you've implemented App Tracking Transparency but the permission request is not appearing on devices running the latest OS, please review the available documentation and confirm App Tracking Transparency has been correctly implemented.If your app does not track users, update your app privacy information in App Store Connect to undeclare tracking. You must have the Account Holder or Admin role to update app privacy information.
I'm using expo-ads-admob and this is how I did it (docs):
I installed expo-tracking-transparency
and added the function on the first part of the application (App.tsx)
import * as React from "react";
import { requestTrackingPermissionsAsync } from "expo-tracking-transparency";
export default function App() {
React.useEffect(() => {
(async () => {
const { status } = await requestTrackingPermissionsAsync();
if (status === "granted") {
console.log("Yay! I have user permission to track data");
}
})();
}, []);
return (
<MainApplication />
);
}
I also added
"plugins": [
[
"expo-tracking-transparency",
{
"userTrackingPermission": "This identifier will be used to deliver personalized ads to you."
}
]
]
To app.json
Then I use the component (everywhere in the app) like this:
<AdMobBanner
bannerSize={
Platform.OS === "ios" ? "fullBanner" : "smartBannerLandscape"
}
adUnitID={
Platform.OS == "ios"
? "IOS_ADMOB_CODE"
: "ANDROID_ADMOB_CODE"
}
servePersonalizedAds={false}
onDidFailToReceiveAdWithError={() => {}}
onAdViewDidReceiveAd={() => {}}
/>
It works, but iOS keep rejecting my application claiming they can't find the permission. I looked everywhere and saw this is the right way to implement this but unfortunately it didn't work.
Thanks in advance!
if you dont have infoplist go to and add the Description here.
enter image description here

Expo-Auth session is not working properly

While implementing google login using the expo-auth-session package , I am getting some error that i don't have any idea about, It has been more than one day since i am stuck in this problem i cannot find a reliable source to use for implementing google login in my expo application. Is there any other way i can implement it in the react native expo application.
The error i am getting are :
WARN Linking requires a build-time setting `scheme` in the project's Expo config (app.config.js or app.json) for production apps, if it's left blank, your app may crash. The scheme does not apply to development in the Expo client but you should add it as soon as you start working with Linking to avoid creating a broken build. [Learn more][1]:
WARN EventEmitter.removeListener('url', ...): Method has been deprecated. Please instead use `remove()` on the subscription returned by `EventEmitter.addListener`.
WARN Possible Unhandled Promise Rejection (id: 2):
Error: Exception in HostFunction: Malformed calls from JS: field sizes are different.
What should i do ??
The link to the documentation that i followed is :-
And this is what i used from the documentation.
import * as Google from "expo-auth-session/providers/google";
import * as WebBrowser from "expo-web-browser";
WebBrowser.maybeCompleteAuthSession();
const [request, response, promptAsync] = Google.useAuthRequest({
expoClientId: expoClientId,
});
const login = ()=>{
useEffect(() => {
if (response?.type === "success") {
const { authentication } = response;
console.log(authentication);
}
}, [response]);
return (
<Pressable style={styles.btn} onPress={promptAsync}>
<Image
source={require("../../../assets/g1.png")}
style={styles.img}
/>
<Text style={styles.text}>Sign in with Google</Text>
</Pressable>
)
}
thank you any help would be appriciated.
In your app.json add following
"scheme":"com.yourpackage.yourapp"
this value must be same as your android.package and ios.bundleIdentifier

Expo useAuthRequest with devTools remote debugging throws error: Calling synchronous methods on native modules is not supported in Chrome

This has to be a common issue, but I can't find anyone else that's had this problem...
Using Expo SDK 42, if I try to enable remote debugging in my project while using Expo's AuthSession.useAuthRequest in the exact same format as the docs
https://docs.expo.dev/guides/authentication/#azure
// this is sample code from Expo, our implementation is basically identical
const [request, response, promptAsync] = useAuthRequest(
{
clientId: 'CLIENT_ID',
scopes: ['openid', 'profile', 'email', 'offline_access'],
redirectUri: makeRedirectUri({
scheme: 'your.app'
}),
},
discovery
);
return (
<Button
disabled={!request}
title="Login"
onPress={() => {
promptAsync();
}}
/>
);
The invocation of useAuthRequest throws this blocking error whenever opening remote debugging with Chrome
Invariant Violation: Calling synchronous methods on native modules is not supported in Chrome.
Consider providing alternative methods to expose this method in debug mode, e.g. by exposing constants ahead-of-time.
Removing the call to useAuthRequest clears the error, so I'm pretty sure that's the problem. But if that's commented out, then I can't debug anything past auth on the app... any ideas on how to get around this?

`useAuthRequest` always returns `dismiss`

SDK Version: 37
Platforms(Android/iOS/web/all): Android (Expo Client)
I’m using useAuthRequest from expo-auth-session to fetch an authentication code for itsme, a Belgian OpenID Connect authentication provider. I'm using the Expo client on Android.
The code looks like this:
export default function SignUpScreen() {
const discovery = useAutoDiscovery('https://e2emerchant.itsme.be/oidc');
const [request, response, promptAsync] = useAuthRequest(
{
clientId: Itsme.CLIENT_ID,
redirectUri: makeRedirectUri(),
scopes: [
'openid',
'service:CURVO_TEST_SHAREDATA',
'profile',
'email',
'phone',
'address'
],
extraParams: {
claims: JSON.stringify({
userinfo: {
'tag:sixdots.be,2016-06:claim_nationality': null,
'tag:sixdots.be,2016-06:claim_city_of_birth': null,
'tag:sixdots.be,2016-06:claim_eid': null,
'tag:sixdots.be,2017-05:claim_photo': null
}
})
}
},
discovery
);
return (
<TouchableOpacity onPress={promptAsync}>Log in</TouchableOpacity>
);
When the “Log in” button is pressed, the following happens:
(OK) The itsme application is correctly opened. I can tell that the scopes have also been correctly communicated.
(OK) I can authenticate within the itsme application with my itsme PIN code.
(OK) The itsme application then closes, which is expected.
(OK) My app is re-opened.
(NOT OK) The response variable becomes equal to { type: 'dismiss' }.
Whatever I do, the response is always “dismiss”. I find it strange because the docs say:
If the authentication is dismissed manually with AuthSession.dismiss() , the result is { type: 'dismiss' } .
However, I never call AuthSession.dismiss().
It looks like it’s failing right at the last step, when it’s supposed to parse the authorization code out of the response URL.
I tried several things:
starting Expo in all three modes: tunnel, lan, localhost
adding a path to the redirect URI, like makeRedirectUri({ path: '/itsme' })
the AppState.currentState “trick” described in a (related?) GitHub issue.
None of these tries worked and I’m out of ideas. Any thoughts or suggestions? Or maybe how to debug inside `expo-auth-session to see what’s going on?
Thank you in advance.