Unable to get authenticated user using Laravel 5.8 and Auth0 - laravel

I have a Laravel 5.8 API that I want to secure using Auth0. So far I've followed every step of this tutorial:
On the front side, Login/logout links are currently implemented in Blade, and this works fine, though the rendered content on the page is done using Vue Router, making AJAX requests to the API for the data.
The default User model in Laravel has been modified to store name, sub, and email per the tutorial, and this populates as well.
The API endpoint is secured using the jwt middleware created during the tutorial, and I can successfully submit a GET along with a hard-coded Bearer auth token in Postman and get a good response.
However, at some point I'd like to be able to pass an access token off to Vue so it can do its thing, but I'm unable to get the current authenticated user. After hitting Auth0, it redirects back to my callback route with auth gobbledlygook in the URL. The route in turn loads a controller method, and everything even looks good there:
// Get the user related to the profile
$auth0User = $this->userRepository->getUserByUserInfo($profile); // returns good user
if ($auth0User) {
// If we have a user, we are going to log them in, but if
// there is an onLogin defined we need to allow the Laravel developer
// to implement the user as they want an also let them store it.
if ($service->hasOnLogin()) { // returns false
$user = $service->callOnLogin($auth0User);
} else {
// If not, the user will be fine
$user = $auth0User;
}
\Auth::login($user, $service->rememberUser()); // "normal" Laravel login flow?
}
I'm not an expert on the framework, but the last line above seems to start the "normal" Laravel user login flow. Given that, shouldn't I see something other than null when I do auth()->user(), or even app('auth0')->getUser()?

Try using a simple tutorial if you're a beginner, I would recommend this
It uses a simple JWT package to create a jwt token which you can get when the user authenticates.
JWTAuth::attempt(['email'=>$email,'password'=>$password]);

Related

Laravel 8 API email verification flow using Sanctum

I'm currently making an API for a mobile app but I think I'm a bit confused with how email verification and authentication is meant to work. I'm attempting to implement the following flow:
User registers in the mobile app and it sends a request to the API
Laravel creates the user and fires off an email
User receives the email and clicks on the link
Laravel verifies the user and redirects them to the mobile app via deep-link
However when the user clicks the email link a "route login not defined" error is rendered.
Which makes sense, because the user is not authenticated at the time. But am I getting this wrong?
Should I authenticate the user prior to sending the email? And will that work, given that we're using Sanctum rather than "regular" authentication?
Currently this is what I'm doing:
// web.php
Route::get('/email/verify/{id}/{hash}', [EmailVerificationController::class, 'verify'])
->middleware('signed') //note that I don't use the auth or auth:sanctum middlewares
->name('verification.verify');
// EmailVerificationController.php
public function verify(Request $request)
{
$user = User::findOrFail($request->id);
if ($user->email_verified_at) {
return '';
}
if ($user->markEmailAsVerified()) {
event(new Verified($user));
}
return redirect()->away('app://open'); // The deep link
}
Is there any security risk here? Should I at any point authenticate the user before or after they click the link?
I wanted to avoid rendering "web views" as much as possible.
I think that the best way is to implement two different paths based on the source of the user.
Regular email validation for users coming from a browser
The user will just follow the link delivered by email, you can do that with or without authentication (maybe with transparent cookie authentication). If the validation is fulfilled redirect them back to the home page.
Mobile users coming from the mobile application
I would send a PIN (with some kind of expire mechanism) via email and ask them to put it inside the APP to verify the account. This can even be protected with auth middleware using the JWT token with the verification API call.
I don't see any security issue with this last one.

react-native facebook login correct implementation

I am developing a mobile app which has a traditional email/password authentication system.
I want to add the facebook login feature to the app. However I do not know how to proceed after the sdk returns that the user is successfully logged in through facebook.
What am I supposed to do in terms of database ? (I'm using Laravel + mysql + laravel passport for authentication)
How do I return a token to the user? How is the flow supposed to be?
Thanks
Few things to do,
The phone number becomes the primary key.
Email and other user information not being collected at first step in sign up becomes nullable().
You need to return token using JSON response.
In Laravel's route/api.php, you need to create an api route.
In the controller, write the logic and return a JSON response (either add the token in response body or response header. It's preferred to add it in the response header.)

Check if user is authenticated in laravel API route

So I know API routes are not supposed to rely on sessions authentication, but my idea was to create some API routes, that could be used if needs be by third-party with proper authentication, but that could also be used internally, ie called to get the data I need for my web pages.
I changed the LoginController so that every time a user logs in, a Personal Access token is generated and stored in the database. When logging out, this token is deleted.
So as not to expose the token to the client side, I would like to use a middleware, that would detect, on an API call, if the request comes from a user who is already authenticated. If that's the case, I would retrieve the Personal Access token that belongs to the user, attach it to the request, and pass it onto the API.
Browser -- Query site.com/api/myRoute --> Middleware adds user's token to request if Auth::check() -- Pass-on request --> Controller
I've created a dummy API route to see if I can detect whether a user is authenticated, but that doesn't seem to work... I guess because the 'auth' middleware is not included.. however, if I do include it, I get redirected to home on every request...
Route::get('/test', function() {
if(Auth::check()) {
dd('Hello logged-in');
} else {
dd('Hello not logged-in');
}
});
Any lead on how to achieve that much appreciated!

Passing accessToken from frontend to PHP API

I've been trying to get authentication working (described below) in my laravel application, following these two tutorials:
https://auth0.com/docs/quickstart/webapp/laravel/01-login
https://auth0.com/docs/quickstart/backend/laravel/01-authorization
On the frontend (angular app):
User clicks log in button and taken to auth0 login page
The user logs in and is redirected back to the callback with the accessToken
The access token is stored on the frontend and passed to Laravel API each request.
On the backend:
User makes a request to my http://localhost/api/route passing the accessToken in the authorisation header
Laravel validates the user is logged in and valid.
Laravel allows access to that route
It works to an extend, but when I try to use postman to access the protected route by passing the accessToken I get the error:
"message": "We can't trust on a token issued by: https://myprojectname.au.auth0.com/."
Is my workflow correct? What am I missing?
Thanks!
Just in case if somebody facing with the same issue. The authorized_iss must contain a trailing slash.
In the laravel-auth0.php file the field,
'authorized_issuers' => 'https://myprojectname.au.auth0.com/'
should be in this form.

Laravel 5.4: how to protect api routes

I have a react app that fetch datas from laravel api defined like so in routes/api.php:
// this is default route provided by laravel out of the box
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
// ItemController provides an index methods that list items with json
Route::resource('items', 'Api\ItemController', array('except' => array('create','edit')));
// this is to store new users
Route::resource('users', 'Api\UserController', array('only' => array('store')));
for example http://example.com/api/items returns the data as intended but it's really insecure since anyone could access it through postman.
How to make those routes only accessible inside the app?
As I'm new to it I don't understand if I need to set up api_token and how?
Do I need to setup Passport?
Is is related to auth:api middleware?
It may sounds really basic but any help or tutorial suggestions would be greatly appreciated
EDIT
End up with a classic session auth. Moved routes inside web.php. Pass csrf token in ajax request. Actually i didn't need a RESTful API. You only need token auth when your API is stateless.
As you are using Laravel 5.4 you can use Passport, but I haven't implemented yet, but i implemented lucadegasperi/oauth2-server-laravel for one of my laravel projects and it was developed in Laravel 5.1
Here is the link to github repository
lucadegasperi/oauth2-server-laravel
Here is the link to the documentation Exrensive Documentation
Just add the package to the composer json and run composer update,the package will get installed to your application , once installed add the providers array class and aliases array class as mentioned in the Laravel 5 installation part of the documentation,
you have to do a small tweak in order to work perfectly cut csrf from $middleware array and paste it into $routeMiddleware array and again run php artisan vendor:publish after publishing the migrations will be created and run the migration php artisan migrate
if you only want to secure api routes for each client like ios, android and web you can implement Client Credentials Grant, or if you need to every user with oauth the you can implement Authorization Server with the Password Grant or some other.,
Never use the client id or other credentials, generating access token in the form, but add it some where in helper and attach it in the request to the api,
Hope this answer helps you.
You could use JWT it's pretty easy to get it to work. You basically generate a token by requesting Username/Password and passing that token in every request that requires authentication, your URL would look like http://example.com/api/items?token=SOME-TOKEN. without a proper token, he doesn't have access do this endpoint.
As for
How to make those routes only accessible inside the app?
If you mean only your app can use these requests, you can't. Basically the API doesn't know who is sending these requests, he can only check if what you are giving is correct and proceed with it if everything is in order. I'd suggest you to have a look at this question

Resources