Failed Silent Auth - Login Required Mobile app

So confused with this problem:

Firstly I have a NextJS web application deployed to website all with Auth0 and all works well.

Now creating an Android (i’ll worry about iOS later) App based on the core code from above, with capcitor.

I am trying to call a protected API on the next JS App above from the android app.

i’ve modified the sign in to use the loginwithredirect and use

Blockquote
import { useAuth0 } from ‘@auth0/auth0-react’;
Blockquote

instead of the nextjs-auth0

Blockquote
import { useUser } from ‘@auth0/nextjs-auth0/client’
Blockquote

On android studio, the login works, but when i try to getAccessTokenSilently() it fails, with “Failed Silent Auth”

I am using the capacitor browser plugin, and i see in Android Studio that the Third Party cookies are the issue. So i believe that this is the issue, But not sure what the steps are to resolve.

File: https://localhost/ - Line 0 - Msg: Third-party cookie will be blocked. Learn more in the Issues tab

Use RefreshTokens and Rotate are all set, i’ve currently set cacheLocation to localstorage.

  • When working with a NextJS web application deployed to a website and an Android app based on the same core code using Capacitor, there are a few important things to consider when trying to call a protected API from the Android app.

  • Authentication Flow: Since you’re using Auth0 for authentication, you need to ensure that the authentication flow is properly implemented for both the web application and the Android app. In the case of the Android app, you’ll need to use the Auth0 Android SDK to handle the authentication process.

  • API Access Tokens: Your API is likely protected using an access token issued by Auth0. In the web application, this access token is typically included in the Authorization header of the API requests. In the Android app, you’ll need to obtain this access token after the user successfully authenticates and include it in the API requests made from the app.

  • Cross-Origin Resource Sharing (CORS): Since your Android app is making requests to the NextJS API, you’ll need to ensure that the API server is configured to allow cross-origin requests from the Android app. This can be done by setting the appropriate CORS headers on the API server.

  • API Endpoint: Make sure that the API endpoint you’re trying to call from the Android app is correct and accessible. If the API is hosted on a different domain or subdomain than the web application, you’ll need to handle this accordingly in the Android app.

Here’s a general approach you can follow:

  • Set up Auth0 in the Android app: Use the Auth0 Android SDK to implement the authentication flow in your Android app. This typically involves creating an instance of the Auth0 client, configuring it with your Auth0 credentials, and handling the login and logout events.

  • Obtain the Access Token: After the user successfully authenticates, you’ll receive an access token from Auth0. Store this access token securely in your Android app (e.g., using the Android KeyStore or secure SharedPreferences).

  • Make API Requests: When you need to make a request to the protected API from your Android app, include the access token in the Authorization header of the request. For example:

val accessToken = getAccessTokenFromSecureStorage() // Retrieve the access token from secure storage
val url = "https://your-api-url.com/protected-endpoint"
val request = Request.Builder()
    .url(url)
    .addHeader("Authorization", "Bearer $accessToken")
    .build()

client.newCall(request).enqueue(object : Callback {
    override fun onResponse(call: Call, response: Response) {
        // Handle successful API response
    }

    override fun onFailure(call: Call, e: IOException) {
        // Handle API request failure
    }
})
  • Configure CORS: On the NextJS API server, configure CORS to allow requests from your Android app. You can use the cors middleware in NextJS to set the appropriate CORS headers. For example:
// next.config.js
module.exports = {
  async headers() {
    return [
      {
        source: "/api/:path*",
        headers: [
          { key: "Access-Control-Allow-Credentials", value: "true" },
          { key: "Access-Control-Allow-Origin", value: "YOUR_ANDROID_APP_ORIGIN" },
          { key: "Access-Control-Allow-Methods", value: "GET,OPTIONS,PATCH,DELETE,POST,PUT" },
          { key: "Access-Control-Allow-Headers", value: "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version" },
        ],
      },
    ];
  },
};

Replace YOUR_ANDROID_APP_ORIGIN with the origin of your Android app (e.g., com.example.myapp).

By following these steps, you should be able to authenticate the user in your Android app using Auth0, obtain the access token, and make requests to the protected API hosted on your NextJS application while including the access HP Instant Ink Subscription token in the Authorization header. Additionally, configuring CORS on the API server will allow cross-origin requests from your Android app.

Still no Joy:

So Next JS Web App i’ve added the CORS to next.config.js

Auth0 Config for the “Regular Web Application”
i’ve added
net.cloudga.cloudga://auth.cloudga.net/capacitor/net.cloudga.cloudga/callback
to callback and CORS

Auth0 Config for “Native”
Added:
net.cloudga.cloudga://auth.cloudga.net/capacitor/net.cloudga.cloudga/callback
to all as above, enabled refresh token
This is the client ID is use in the Capacitor APP code

Created API https://cloudga.net/api, have done no changes to this other than allow access to via machine to machine to the “Regular Web Application”

Added https://cloudga.net/api to the audience in capacitor app login and getAccessTokenSilently on a test page on the app

I can Login, I get the Token, do a call using the CapacitorHttp.request with the header options that include the Token received.

However I’m still getting 401. Its not reaching any code on the API, as it is using withApiAuthRequired.

FYI the “Regular Web App” is hosted on Azure web application

I’m thinking the issue is CORS, but not sure what i’m missing

so i have now sorted this issue.

I have been informed that withAPIAuthRequired, does not work with tokens from the mobile app

so have refactored all of my authenticated API’s to verify the user

const sid = await verifyUser(req, res)

this will return the sub / auth0id from the logged in user regardless of cookie or token:

using:

import { jwtVerify, createRemoteJWKSet } from “jose”;

export default async function verifyUser(req: NextApiRequest, res: NextApiResponse): Promise<any | undefined> {

let usersub = ''
if (req.headers.authorization) {

    const token = req.headers.authorization.substring(7)
    const JWKS = createRemoteJWKSet(new URL('https://<AuthDomain>/.well-known/jwks.json'))

    const { payload } = await jwtVerify(token, JWKS, {
        audience: 'https://<DOMAIN>/api',
    })

    usersub = payload.sub ?? null
}
else {
    const session = await getSession(req, res)
    if (session) {
        usersub = session.user.sub ?? null
    }
    else {usersub =null }

}

if (usersub) {
    return usersub
}
else {
    return null
}

return null

}