Native app + Laravel API (both with Auth0)

TLDR: How do I get an JSON response from Laravel API, for users authenicated on Auth0 on a native platform?

So I have a Nativescript-Vue app running with Auth0 succesfully (using this plugin: https://github.com/charsleysa/nativescript-auth0). I also have a Laravel server succesfully working with both the regular web app authenication (Auth0 Laravel SDK Quickstarts: Login) and an API endpoint (Auth0 Laravel API SDK Quickstarts: Authorization).

When the user authenicates on the native app I get information such as an accessToken (although it seems quite short? idToken, refreshToken, etc.) An example of this shown in the image below:

Now I want to send an HTTP request to my Laravel web server from the Native app to fetch someday in a json format (i.e. data that is stored on the laravel server). When I send this request, the Laravel server not only needs to authenicate the request BUT also identify the user sending the request from the native app.

This is where I feeling Iā€™m missing somethingā€¦ with the regular web app authenication the docs only get me so far as authenicating through a standard form n etc. but not with an access token. The API docs on the other hand seem to really ā€œidentify a userā€ and doesnā€™t work with my native app as I expected.

What am I missing?

So to follow up on this, I realized that if I change the audience for the webAuthentication() as shown here:

image

To match the Identifier of my Auth0 API, then I am able to successfully authenicate and call the Laravel API.

ā€¦still Iā€™m unsure on how to identify the user requesting the API call?

Now one way I can do this, is to include the userā€™s details such as the email as an additional field in the GET request itself. Then after the Laravel API authenicates the request, it can search for the user from an email list and then proceed to use that as the user.

This would work completely fine but I feel like its a bit botchy? As in theory it allows for any authenicated request to get any userā€™s data provided the specific email is given? I would rather the access Token only allow for a specific userā€™s details if that makes senseā€¦

Since in case tokens are comprised they shouldnā€™t be able to be used to get other userā€™s information.

Delving into this further Iā€™m getting more and more lost :sweat_smile:!

So on Auth0 I had two applications: one regular web application for Laravel, one Native application for Nativescript-Vue. As well as this one created 1 API for Laravel. Here are some images to make it clearerā€¦

For my Native App when I originally logged in the user, I had Auth0 log them through the Native Application - I thought that you had to create a Auth0 application for each type of platform you deploy toā€¦

But I added aditional callbacks for my regular web application and modified Token Endpoint Authentication Method to none, then I was able to authenicate the user on my native app through the Auth0 ā€œweb applicationā€ ? Bit confused by thisā€¦ so does that mean my native application auth0 is redundant? Can I just log/sign up users through the Auth0 Web Application that is linked to Laravel?

Additionally when I authenicate the user, I set the audience as for the Auth0 API which is linked to Laravelā€¦ this then gives me an jwt access token (which allows to me to access my Laravel API routes with a jwt middleware BUT not my standard Laravel routes secured by the auth middleware) and a seperate id token (which contains user info).

Nowā€¦ Iā€™m still stuck on trying to making it so that my Laravel API authenicates the user, and ONLY allowing them user specific information. At this rate since Iā€™m on a time deadline, I might just include the userā€™s email as an additional field in the GET request and then do processing that wayā€¦ Annoyingly this would technically allow any authenicated user to search for other users data >.<

WOOOOO managed to find a solution :smiley:

So when I do the authenicate with the jwt access token, I noticed that the jwt itself contains a ā€œsubā€ in the payload data ā†’ therefore I can use this with my user repository in Laravel to find the specific ā€œUserā€ model, and then do following actions from there!

Okay so now I think it should be all goodā€¦ but I do still have a couple of doubts if Iā€™m doing everything by best practice, Iā€™m still unsure about this whole Auth0 ā€œapplicationsā€ thing? i.e. should I have a separate application for my Laravel Web App and Native App?

Also was I correct in implementing BOTH Auth0 Laravel SDK Quickstarts: Login and Auth0 Laravel API SDK Quickstarts: Authorization or is there a better way in which only one is required?

@thush - First, I appreciate your detailed posts here and checking back in with what you came up with. The time you spent here will definitely help other folks. Hopefully I can add a bit of clarity to this.

If I understand correctly ā€¦ you are building a native application. While I canā€™t speak to Nativescript-Vue, I can hopefully help with the idea of a native app calling a Laravel API. Iā€™ll answer some of your previous posts as well in case you still had some lingering questions.

When the user authenicates on the native app I get information such as an accessToken (although it seems quite short?

The access token you were seeing in your first post was one that is meant to be used against our userinfo endpoint (sends back the same user data that comes with the ID token).

So to follow up on this, I realized that if I change the audience for the webAuthentication() as shown here ā€¦ To match the Identifier of my Auth0 API, then I am able to successfully authenicate and call the Laravel API.

You got it :+1: Adding that audience to the request tells Auth0 that the native application wants an access token.

This would work completely fine but I feel like its a bit botchy? As in theory it allows for any authenicated request to get any userā€™s data provided the specific email is given?

Once again, totally on the right track here. When your native app sends a user to login with that audience (and scope, if your API is built to provide different capabilities based on different scopes), itā€™s requesting access to the API on behalf of a very specific user, the one logging in. As such, the API should only be providing the data that that specific user has access to.

Since in case tokens are comprised they shouldnā€™t be able to be used to get other userā€™s information.

Even if it wasnā€™t compromised, you still want that the data returned to be specific for the user (and scope) of that access token.

I thought that you had to create a Auth0 application for each type of platform you deploy toā€¦

You should have an Application created for each application that youā€™re creating that a user can log into using Auth0. Thatā€™s a bit of a mouthful but ā€¦ the native app definitely should have an Application and the Laraval-served API should have itā€™s own API. If youā€™re using Auth0 to log in to the ā€œemit analyticsā€ app as well, then that record is fine. The ā€œemit APIā€ test application is created automatically and can probably be deleted.

But I added aditional callbacks for my regular web application and modified Token Endpoint Authentication Method to none, then I was able to authenicate the user on my native app through the Auth0 ā€œweb applicationā€

Your tenant doesnā€™t really care what app is doing what, really, and the application type thatā€™s there is mostly to help guide you with the UI. If you create a regular application and then give that Client ID and Domain to a native app, it should work fine.

this then gives me an jwt access token (which allows to me to access my Laravel API routes with a jwt middleware BUT not my standard Laravel routes secured by the auth middleware) and a seperate id token (which contains user info).

Exactly correct.

So when I do the authenicate with the jwt access token, I noticed that the jwt itself contains a ā€œsubā€ in the payload data ā†’ therefore I can use this with my user repository in Laravel to find the specific ā€œUserā€ model, and then do following actions from there!

:boom: Exactly

but I do still have a couple of doubts if Iā€™m doing everything by best practice, Iā€™m still unsure about this whole Auth0 ā€œapplicationsā€ thing? i.e. should I have a separate application for my Laravel Web App and Native App?

I explained that above but it canā€™t hurt to go through it again.

Each entity that is accepting logins (or obtaining access tokens to call APIs or both) should have its own application, which will generate its own Client ID that you use in the individual applications. If both the web app and the native app pull from the same pool of users (as in, if I log into the web application with the same user account as the native application) then they should share the same connections (same database, if youā€™re using that, same social connections).

Hopefully that helps iron things out. Itā€™s clear to me from this thread that we could be doing a better job of explaining all of this in our quickstarts and documentation. Once again, thank you very much for typing all of this out!

3 Likes

Thanks so much @josh.cunningham again, you went through everything in detail and I feel like I have a lot more clarity now - I think Iā€™m pretty confident in the way Iā€™ve built the authenication flow now :smiley: !

3 Likes

Perfect to hear that @thush!

Now you know who to reach out to!

1 Like

Just following back on this to say that Iā€™ve succesfully managed to integrate Auth0 authenication flow with my Nativescript-Vue app. Works beautifully and I canā€™t have managed to do it with @josh.cunningham, thanks so much!

Iā€™ll make a ā€œbriefā€ run down of what I had to do in case anyone else wants to implement something similar:

  1. Implement Auth0 authenication with Laravel (Auth0 Laravel SDK Quickstarts: Login). Implement custom user handling as well, I modified my CustomUserRepositoryā€™s method of upsertUser( $profile ) slightly to return a laravel user instead since Iā€™m using Laravel Spark and it breaks without thatā€¦
  2. Implement API Auth0 authenication with Laravel (Auth0 Laravel API SDK Quickstarts: Authorization)
  3. Implement Auth0 authenication for Nativescript, there is community support (https://www.npmjs.com/package/nativescript-auth0), I had a little trouble with android at the start but after this issue (Android - Parameter 'prompt' set to 'none' - callback URL issue Ā· Issue #61 Ā· sitefinitysteve/nativescript-auth0 Ā· GitHub) got it working.
  4. On the Auth0 dashboard, at this stage you should have 2 applications, ignoring test applications (1 as a ā€˜regular web applicationā€™ for your Laravel and 1 as ā€˜nativeā€™ for your Nativescript). Also on the Auth0 dashboard, you should have an 1 API for your Laravel API, ignoring the Auth0 system API.
  5. To now communicate between a authenicated user on your Nativescript App and your Laravel API, make sure that when you authenicate the user, you use your APIā€™s identifier as the audience. In Nativescript this looks like this:

    You can find the audience parameter hereā€¦
  6. Now you should be able to do requests to your Laravel API with the accessToken, for example:
    .
    These would follow through to API routes that look this in Laravel (see the earlier API Auth0 Laravel docs):
  7. The final step involved me needing my Laravel server (which I set up with a custom user repository, see https://auth0.com/docs/quickstart/webapp/laravel/01-login#optional-custom-user-handling), to identify which user was doing the API request. I did this with a little hack in the CheckJWT.php middleware like this:

    Make sure you followed the custom user handling section carefully, to include the userā€™s ā€œsubā€, this is what auth0 uses to identify your user and it is how I made Laravel know which user is requesting the API.
  8. Now all your following controllers have access to auth()->user() helpers, thus you can return any user specific data!

I managed to get this working for both Android and iOS, with userā€™s profile (i.e. through Auth0 and the Laravel API) being shared accross all platforms. Also on the plus using Nativescript-Vue and Laravel with a frontend of Vue, made front end codebase sharing a joy!

Edit: Mods (I assume @josh.cunningham, @konrad.sopala) could you guys add additional tags to this? Maybe like Native, Nativescript, JWT, etc. might help additional people?

2 Likes

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