What Need to Pass for Logout Passport Function - laravel

Using Passport for Access Token and Refresh Token. For Logout function what should be Posted/Get and What will be the URL?
API Route:
Route::group([
'middleware' => 'auth:api'
], function() {
Route::get('logout', 'api\LoginController#logout');
});
public function logout(Request $request)
{
$request->user()->token()->revoke();
return $this->loggedOut($request);
}
URL: http://localhost:8000/api/auth/logout ???
What should be posted for this URL ?

If you have a prefix of auth then that should be a correct logout route. If not, remove auth from url.
Token should be present in axios headers, since the logout route is under auth:api middleware, and you will revoke it inside logout method.
Code snippets as requested in the comment
Once you login the user you add token to axios headers
axios.defaults.headers['Authorization']='Bearer ' + token;
axios.defaults.headers['Content-Type']='application/json';
When you make logout request
axios.get('/api/auth/logout')
.then(response => {
localStorage.removeItem("token");
localStorage.removeItem("token_type");
delete axios.defaults.headers['Authorization'];
}).catch(error=> {
});
And in your logout method in controller you revoke the user token
$request->user()->token()->revoke();
return response()->json([
'message' => 'Successfully logged out'
]);

You have to pass access_token in Authorization header which you have got after successfully logged in.
Your logout route is protected by passport so When calling routes that are protected by Passport, your application's API consumers should specify their access token as a Bearer token in the Authorization header of their request.
For example, when using the Guzzle HTTP library:
$response = $client->request('GET', '/api/logout', [
'headers' => [
'Accept' => 'application/json',
'Authorization' => 'Bearer '.$accessToken,
],
]);
from the doc laravel passport passing access token

Related

Register user with Vue.js and Laravel

Created a page of login with vue.js.
Sent the data to a laravel controller to create a new user.
I sent the data to a controller in laravel to create a new user.
After creating the user, I'm trying to redirect to home, with the user authenticated, but when redirecting to home, it goes to login page.
Vue requisition
register(){
axios.post('/api/register', this.form)
.then(response => {
window.location.href = "/home";
});
}
Route API
Route::post('register', 'Api\RegisterController#register');
Controller Laravel
public function register(Request $request){
$data = $request->validated();
$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
Auth::login($user);
Auth::guard()->login($user);
// Auth::loginUsingId($user->id);
return response()->json(['message' => 'Salvo com sucesso.','user' => $user]);
}
Route WEB, that is accessed after registration:
Route::group(['middleware' => ['auth']], function () {
Route::get('/home', function(){
return view('home')
});
});
I tried with the code,redirect to home, authenticated , but it is going to the login screen, because of the middlware.
Is there any way to go to the home screen automatically authenticated after registration, without having to log in?
When you're registering using Ajax, Laravel is not using sessions to prevent authentication from unsafe origins, so you end up having no authentication for the current user session even after login.
You need to use other auth guard for stateless auth. There are a bunch of variants, but most simple for you will be Sanctum, which store XSRF-TOKEN in cookies and take auth data from there instead of session.
As an alternative, you may consider using JWT, or other token based authentication, but you still will probably experience some troubles with session as I see you not having your front-end as SPA:
window.location.href = "/home";

401 (Unauthorized) while fetching user using laravel Sanctum with api token authentication [duplicate]

This question already has answers here:
Authorization header not reaching the server in laravel project
(3 answers)
Closed 2 years ago.
I watched this tutorial for api token authentication with laravel sanctum. When logging in, I retrieve a Bearer token which I add to the axios header. But when trying to fetch the user via /api/user, I get a 401. Notice that I don't use CSRF tokens since I'm using Sanctum Api Token Authentication and not SPA authentication.
I have an api file for all axios requests that looks like
let axiosInstance = axios.create({
baseURL: 'http://some-url.local/api',
})
let api = function () {
let token = localStorage.getItem('token');
if (token) {
axiosInstance.defaults.headers.common['Authorization'] = `Bearer ${token}`;
}
return axiosInstance;
}
export { api }
Some auth functions
import {
api
} from 'boot/axios'
export default {
register(form){
return api().post('/register', form)
},
login(form) {
return api().post('/login', form)
},
logout(){
return api().post('/logout')
},
auth(){
return api().get('/user')
}
}
LoginController
class LoginController extends Controller{
public function login(Request $request){
$this->validate($request, [
'email' => 'required|email',
'password' => 'required',
'deviceName' => 'required'
]);
$user = User::where('email', $request->email)->first();
if (!$user || !Hash::check($request->password, $user->password)) {
throw ValidationException::withMessages([
'email' => ['The provided credentials are incorrect.'],
]);
}
return $user->createToken($request->deviceName)->plainTextToken;
}
public function logout(Request $request)
{
$request->user()->tokens()->delete();
return response()->json('logout successful', 201);
}
}
Route in routes/api.php
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});
I use HasApiTokens in my User Model, have 'prefix' => 'api' in config/sanctum.php, 'paths' => ['api/*'] in config/cors.php and have 'api' => ['driver' => 'sanctum',...] in my config/auth.php
I watched that tutorial twice and copied everything exactly the same (except that I'm using Quasar framework), searched all over google and stackoverflow... I don't understand, please help! I do recieve a Bearer token, so the app thinks I'm logged in, but can't fetch my user data. In part 1 of the tutorial mentioned above, the same is done, but with SPA authentication (csrf) and this one did work!
UPDATE
It seems it works with php artisan serve on http://127.0.0.1:8000/, but not with MAMP serving on http://some-domain.local or on a public domain
Why...
SOLVED!
For anyone else with this problem:
It seemed that my Bearer token was removed from the request on the laravel endpoint for some reason (I still don't know why).
Adding a custom header (X-Authorization) to axios and resolving server side with a middleware fixed it! More info here

Laravel undefined method revoke

I am test building an application, using Laravel, Laravel passport and socialite to login and logout users in a vue SPA. No problem to login and create users, it is only when I try to logout users that I get the error: call to undefined method: revoke
This is in Auth\LoginController:
public function logout(Request $request) {
$request->user()->token()->revoke();
return response()->json([
'message' => 'Successfully logged out.'
]);
}
This is in Api.php:
Route::group(['middleware' => 'auth:api'], function(){
Route::post('/logout', 'Auth\LoginController#logout');
});
This is axios called in vue SPA:
logout() {
axios.post('/api/logout')
.then(res=>{
console.log(res.data);
});
}
If revoke works I should get the message for successfully logged out. Any help here is appreciated.
Additional: in my LoginController handleProviderCallback function to handle the socialite logins I have this
auth()->login($user);
$tokenResult = $user->createToken('Personal Access Token');
$token = $tokenResult->token;
$token->expires_at = Carbon::now()->addWeeks(1);
$token->save();
return response()->json([
'access_token' => $tokenResult->accessToken,
'token_type' => 'Bearer',
'expires_at' => Carbon::parse($tokenResult->token->expires_at)->toDateTimeString()
]);
The outcome is when users click on social logins, it shows the access token. I have always thought laravel_token from cookies is the JWT which Laravel automatically handles. Now I am not very sure. So if with this additional code, the access token is the right way to handle JWT, how do I pass the response into Vue since it is a redirect from socialite, not an Axios request?
After the JWT is tested i can try out on the logout again to see if the JWT is the issue.
Are you sure that the user has a token ? And are you using the HasApiTokens trait in your User model ?
I have solved this with the default Auth::logout(). The code for the 'Personal Access Token' is not needed. In the documentation of passport Laravel attaches a JWT in a cookie called laravel_token which passport will check if user is authenticated.

API login from android app using laravel 5.3 passport

For two days I am digging google but could not find the starting thread for my problem, now I am out of option. Please help me with some direction/howTo
I have a web application running built with laravel 5.3, I have installed passport as described here . if I go /home its showing perfectly.
Now I have to make an android app from which
An already existing user of web app can login
get all the task list of that user TaskModel (ons_tasks(id, title, description))
routes related only
in web.php
Auth::routes();
in api.php
Route::get('/user', function (Request $request) {
return $request->user();
})->middleware('auth:api');
Route::group(['middleware' => ['auth:api']], function () {
Route::get('/test', function (Request $request) {
return response()->json(['name' => 'test']);
});
Route::get('/task/list', function (Request $request) {
$list = \App\Model\TaskModel::all();
return response()->json($list);
});
});
To login : if I send post request /login with email & password get the TokenMismatchException error but Where do I obtain a token for
android app in mobile? Do I need the Auth::routes() in the api too?
if then what else Do I need to just login and get a token so later I
can send it for getting the task lists.
Secondly,
If I go to /api/test it redirects me to /home page without
showing any error !!!
Thanks in advance.
To authenticate with your Passport-enabled API
You'll need to use the Password Grant Client in this situation, see this section of Passport's documentation.
Once you've generated a Password Grant Client, using:
php artisan passport:client --password
You will need to request an access token from your application, and send it with your subsequent requests, in order to access the protected auth:api middleware routes.
To get an access token, send a request to your app's /oauth/token route (this is a PHP implementation obviously, ensure you are correctly formatting below request in your Java implementation):
$http = new GuzzleHttp\Client;
$response = $http->post('http://your-app.com/oauth/token', [
'form_params' => [
'grant_type' => 'password',
'client_id' => '<client id returned from the artisan command above>',
' client_secret' => '<secret returned from artisan command above>',
'username' => 'taylor#laravel.com',
'password' => 'my-password',
'scope' => '',
],
]);
return json_decode((string) $response->getBody(), true);
Ensure you add the client_secret and client_id that was returned from the artisan call above, and ensure username and password references a valid user in your database.
If everything is fine here, you should receive an access_token and refresh_token in the response. The access_token is what you need to authenticate using the auth:api guard. To correctly pass this back to your api, you will need to send your subsequent requests with the headers Authorization: Bearer <your accessToken> and Accept: application/json
For example, to access your "test" route:
$response = $client->request('GET', '/api/test', [
'headers' => [
'Accept' => 'application/json',
'Authorization' => 'Bearer '. <accessToken from /oauth/token call>,
],
]);
If you've set these correctly, you should see a JSON response with the array you have specified.
Why is /api/test redirecting me with no error?
You are requesting a route with the auth:api middleware. This will redirect you as you have not specified the correct headers as described above, this is expected behavior.
Hope this helps.

TokenGuard class always need api_token

I am using AngularJs and Laravel 5.4
In the default guard, I changed the web guard to api. Finally it looks like below.
'defaults' => [
'guard' => 'api',
'passwords' => 'users',
],
when i send the request using username and password from Angular Js....I always get invalid credentials because..
TokenGuard class has a method called validate which expects api_token value but I am on the login page.
I am assuming that in order to get the token, I need $this->guard(web) in login method?
Is it correct approach or Am I missing something?
By default all routes defined in routes/api.php have the api middleware as defined in app/Providers/RouteServiceProvider::mapApiRoutes(). Therefore, you always need to pass api_token.
What you can do is, in your api routes, define the login route like this
Route::post('login', 'api\AuthController#login'); //out of the group
And post from AngularJS
$http.post({
url: 'http://localhost/api/login',
data: $scope.userda,
headers: {
Authorization: ''
}
}).then(...)
Then define all your other routes in a group with auth:api
Route::group(['middleware' => 'auth:api'], function(){
//Other routes here
});
In angular, set the Authorization headers with the value of api_token. So before login, it will be empty and after login it will have the value of the user api_token.

Resources