I'm not sure if I'm using the correct method for my problem.
I would like to get Infos via Axios. For example: calling: /api/user with Axios gets me the user, but I don't want to see the information when I go on domain.test/api/user.
I even want to use API calls to get Results of Functions even if the User is a Guest.
I installed everything there is on the Laravel Documentation for API, but still I'm not sure how the user gets the Token.
So if I call:
axios.get('/api/user')
.then(response => {
console.log(response.data);
});
I get from the network tab {"message":"Unauthenticated."}. (I didn't forget to set: ...Middleware\CreateFreshApiToken::class and everything there is).
I think my problem is that I didn't register the User correctly. I got my two keys what should I do with it?
And then it's weird, reading the blog https://laravelcode.com/post/laravel-passport-create-rest-api-with-authentication, they use
$success['token'] = $user->createToken('MyApp')->accessToken;
But I don't get it. Where do I save it? I'm super confused, because every blog about shows Laravel Passport completely differently.
Or am I doing it wrong?
Passport is an OAuth2 server implementation which offers several different authorization strategies. While it is certainly possible to use Passport for authentication, it's primary purpose is authorization. This is done via token scopes. The type of token you choose to issue depends on your intended purpose with the API and whom your intended target is to be consuming your api.
Let's start with the following:
$success['token'] = $user->createToken('MyApp')->accessToken;
Here they are creating Personal Access Tokens. This is the simplest means of consuming your api, since clients are able to create the token themselves as needed and are long lived.
The Password Grant strategy is also a good option. A common approach when using this strategy is proxying authentications to Passport internally and merging the client id and secret into the request in a middleware.
public function handle($request, $next) {
return $next(tap($request, function($request) {
$request->merge([
'client_id' => config('services.passport.client.id'),
'client_secret' => config('services.passport.client.secret')
]);
// do any other pre-request work needed here
}));
}
Setup
To get started with Passport, run the command:
php artisan passport:install
This will create the encryption keys as well as a personal access and password grant client types, which will be stored in your database in the oauth_clients
table.
Guard and Middleware
API routes need to be using the api
guard, done by setting auth:api
middleware on the route group(s) or Controller constructor.
// using via constructor
public function __construct()
{
$this->middleware('auth:api');
}
// via a route group
Route::group(['middleware' => ['auth:api'], function() {
// your api routes
});
Passport Routes
Your user model needs to be using the trait HasApiTokens
and within the AuthServiceProvider
call Passport::routes()
in the boot
method.
public function boot()
{
$this->registerPolicies();
Passport::routes();
// this is also an ideal time to set some token expiration values
Passport::tokensExpireIn(now()->addDays(15));
Passport::refreshTokensExpireIn(now()->addDays(30));
}
To use the personal access token strategy for authentication, you need to create your own login and logout routes instead of using the builtin Laravel auth mechanisms.
Referring to the tutorial in your question, they have defined the following routes:
Route::post('login', 'API\PassportController@login');
Route::post('register', 'API\PassportController@register');
and the login method implemented as:
public function login(){
if(Auth::attempt(['email' => request('email'), 'password' => request('password')])){
$user = Auth::user();
$success['token'] = $user->createToken('MyApp')->accessToken;
return response()->json(['success' => $success], $this->successStatus);
}
else{
return response()->json(['error'=>'Unauthorised'], 401);
}
}
This is expecting a ajax request with an email and password to be posted to login
and if successful it responds with an access token.
Storing/Using the Token
This token must be stored client side, either in a cookie or local storage, for example, and then added to every request from the client there after. You'll add the token to the Authorization
header in client requests.
// Use a response interceptor to check for a token and put it in storage
axios.interceptors.response.use(response => {
// store the token client side (cookie, localStorage, etc)
if (response.data.token) {
localStorage.setItem('token', token)
}
return response
}, error => {
// Do something with response error
return Promise.reject(error);
});
// Use a request interceptor to add the Authorization header
axios.interceptors.request.use(config => {
// Get the token from storage (cookie, localStorage, etc.)
token = localStorage.getItem('token')
config.headers.common['Authorization'] = `Bearer ${token}`
return config;
}, error => {
// Do something with request error
return Promise.reject(error);
});
Accessing the Authenticated User
In order to get the user, pass the 'api'
parameter to the auth()
helper, Auth
facade, or through the request:
$user = auth('api')->user();
$user = Auth::user('api');
$user = request()->user('api');
Keep in mind personal access tokens are long lived, so it's up to you to decide when and how they should expire.
Any http client can be used to make api requests, axios is a very common option and included with each Laravel installation.