How get access token after autorization laravel sanctum? - php

Hello i'm newbie in laravel. I use for authorization sanctum. But i want that some request can available for authorization user (i use laravel for only api, on front i use angular 2).
web.php:
Route::group(['middleware' => ['auth:sanctum']], function () {
Route::post('api/user-information', function(Request $request) {
return response()->json([ auth()->user()]);
});
// API route for logout user
Route::post('api/logout', [AuthController::class, 'logout']);
});
How can I get access token after success autorization user that i can send request for middleware routes. Because if i have request withous access token i always send null in 'api/user-information'. Please help me resolve this problem.

You could better make a new function in a controller, probably the AuthController. In this function you can validate fields
$validatedData = $request->validate([
'email' => ['required', 'email'],
'password' => ['required'],
]);
With the validated data you can use Auth::login($validatedData);
Source: https://laravel.com/docs/9.x/authentication#login-throttling

Welcome to Laravel! I am assuming you have login method that authenticates user. You can create a token in that method and pass it to your frontend.
public function login(Request $request)
{
$request->validate([
'email' => 'required|email',
'password' => 'required',
]);
$user = User::where('email', $request->email)->first();
if (! $user || ! Hash::check($request->password, $user->password)) {
return ['status'=>0,'message'=>'Invalid Credentials','data'=>[]];
}
$data = [
'user'=>$user,
'token'=>$user->createToken('MyToken')->plainTextToken
];
return ['status'=>1, 'message'=>'Login Successful!', 'data'=>$data];
}
If you just need to pass the token, you can simply return token in the response and then pass it in request header (Authorization) of your Angular applcation to access the API routes protected by Sanctum middleware auth:sanctum
return $user->createToken('MyToken')->plainTextToken;
Also since you are going to use Laravel for API, I would suggest you put all your routes in routes/api.php file.
The routes in routes/api.php are stateless and are assigned the api middleware group. The prefix '/api' is applied to all the routes defined in api.php
You can read more about it in Laravel Documentation
Issuing API Tokens
The Default Route Files

Related

Laravel - API login authentication check

As part of learning Laravel API, login and authentification I've created API login route which which works fine, user is loged-in and JSON response returns token that needs to be put into Bearer Token field and API resource movies route which allows CRUD operations.
I'm using Postman for testing and when I go directly to GET /api/movies route without login or pasting token into Bearer Token I cannot access this route which is desired outcome if user is not authenticated and got this message:
Symfony\Component\Routing\Exception\RouteNotFoundException: Route [login] not defined. in file /home/****/Projects/movie-api/vendor/laravel/framework/src/Illuminate/Routing/UrlGenerator.php on line 444
What I'm trying to do, instead of this message to return JSON response that user is not authenticated but don't know how or where to put that code.
I've tried with Auth:check() in api.php and in my AuthController, but could not make it work and could not find anything in Laravel documentation regarding this.
This is my api.php and AuthController.php:
api.php
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\API\MovieController;
use App\Http\Controllers\API\AuthController;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::post('register', [AuthController::class, 'signup']);
Route::post('login', [AuthController::class, 'login']);
Route::middleware('auth:sanctum')->group(function() {
Route::resource('movies', MovieController::class);
});
AuthController.php
<?php declare(strict_types=1);
namespace App\Http\Controllers\API;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\Controller;
use Validator;
use App\Models\User;
use App\Providers\MovieApiProvider\ApiResponseServiceProvider as ApiResponseService;
class AuthController extends Controller
{
private ApiResponseService $apiResponseService;
public function __construct()
{
$this->apiResponseService = new ApiResponseService;
}
public function signup(Request $request)
{
$validator = Validator::make($request->all(), [
'name' => 'required',
'email' => 'required|email',
'password' => 'required',
'confirm_password' => 'required|same:password',
]);
if ($validator->fails()) {
return $this->apiResponseService->responseError('Error validation', ['error' => $validator->errors()]);
}
$input = $request->all();
$input['password'] = bcrypt($input['password']);
$user = User::create($input);
$success['token'] = $user->createToken('MyAuthApp')->plainTextToken;
$success['name'] = $user->name;
return $this->apiResponseService->responseSuccess($success, 'User created successfully.');
}
public function login(Request $request)
{
if (Auth::attempt([
'email' => $request->email,
'password' => $request->password
])) {
$authUser = Auth::user();
$success['token'] = $authUser->createToken('MyAuthApp')->plainTextToken;
$success['name'] = $authUser->name;
return $this->apiResponseService->responseSuccess($success, 'User signed in');
} else {
return $this->apiResponseService->responseError('Unauthorised.', ['error' => 'Unauthorised'], 401);
}
}
}
Can someone help with this?
Laravel assumes you are using a browser, so when checking authentication, you are redirected to a login page. All you need is:
Accept: application/json

Where is the middleware key for Laravel Sanctum defined?

To protect and authenticate all incoming routes in Laravel using Sanctum, we have to attache the sanctum authentication guard to our routes within routes/api.php route files:
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});
My question is about the middleware key auth:sanctum. Where is it defined/registered?
As document says
To protect routes so that all incoming requests must be authenticated,
you should attach the sanctum authentication guard to your protected
routes within your routes/web.php and routes/api.php route files.
if you see Laravel\Sanctum\SanctumServiceProvider in register method
public function register()
{
config([
'auth.guards.sanctum' => array_merge([
'driver' => 'sanctum',
'provider' => null,
], config('auth.guards.sanctum', [])),
]);
if (! app()->configurationIsCached()) {
$this->mergeConfigFrom(__DIR__.'/../config/sanctum.php', 'sanctum');
}
}
While registering they are setting sanctum guard.So sanctum is not middleware its guard
Ref:https://laravel.com/docs/8.x/sanctum#protecting-routes
Ref:https://github.com/laravel/sanctum/blob/2.x/src/SanctumServiceProvider.php

Auth user showing Null in outside of auth api passport

I am developing an app where I am fetching user details with Laravel passport API get method with query string.
But when I put that route in auth API it shows "route login not found" and when I put outside auth API it shows Null when I call Auth::user().
Here is my route and my API with method:
Route::post('login', 'AuthController#login');
Route::post('register', 'AuthController#register');
Route::get('GetUserClaims', 'AuthController#GetUserClaims');
Route::group(['middleware' => 'auth:api'], function(){
//Route::get('details', 'AuthController#details');
//Route::get('GetUserClaims', 'AuthController#GetUserClaims');
});
http://xxx.xxx.xxx.xxx/public/api/GetUserClaims?userKey=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6Ijg3M2E4NTdhZmViMGVhMzAzNWQ5ZGU5NGZmNTUzMmI4NGUyMDZjZjE0MjRhYzQxZjI0YjUwYjdmZjc4OWZmYjM5YzhmNjBlZjRmYzM0OTQzIn0.eyJhdWQiOiIxIiwianRpIjoiODczYTg1N2FmZWIwZWEzMDM1ZDlkZTk0ZmY1NTMyYjg0ZTIwNmNmMTQyNGFjNDFmMjRiNTBiN2ZmNzg5ZmZiMzljOGY2MGVmNGZjMzQ5NDMiLCJpYXQiOjE1ODUwODU5NDksIm5iZiI6MTU4NTA4NTk0OSwiZXhwIjoxNjE2NjIxOTQ5LCJzdWIiOiI2Iiwic2NvcGVzIjpbXX0.VXKRTTpZxMGq4gR8kdu9qREBvhxSfPz4WureEYCpr-nh-qMFqkuR9Q10oa4AotmNmIABRFb_ijyrpt1AVJOpPU4b0R4lEnUWq746wh3etBg37fuSvDx8XDwF84NcOyU1GNnXDZ0KLbwr4YjrOqtuPNBAtkDEPHOKUYdxHvYOUSqt8YIx-L1p2ijHEvYDKroG8-B9mZs97HCtgSpwqTv7b5I0hEV4b1Ifkm24qDhoRMvaSYDFGcu52VWfwPjMEq6NPDYwwBx9Jpv_wv8-UA8BZPqECzE-D7xw46X4IhUNg9PyGxhtWbMvipz1E1OFzb_lBmgYTU5JVx0s0wmmcjqAq4jlfHNarUdBQGziJR4m3rLBGYNtLmqQ4kR1knrhaR-qQYaKiQNknxtb7c_HG724G_XSYkzFJZUalLFtQkDYpXSSP-QgzKFrQHblE6Led2AwPqt4S4svDOht5hqg29TejNbggIztj_fs9u2cwso1VvPjAM1LLG8chzVT5PM6YTihDGaVf4VEUaQmClgG64pEq2TmJISTLsplqlG1wn2BTdmCcO69VZYBvLJvjDlm942RGAYaNHD7Wt3RbJxMOH3RF8OGRP_H2IvIwtWz4x29dDUg8fMEKlA-nM1A8wsrK-YFkbwrY-IOzHl-4MdPopmXiFViB5RPMkQdCMd0ItWTjgA
public function GetUserClaims(Request $request)
{
if ( $request->has('userKey') ){
$user = Auth::user();
$token = $request->userKey;
var_dump($user);
//$token='Bearer '.$request->bearerToken();
//$request->header('Authorization',$token);
//return response()->json(['user' => auth()->user()], 200);
//return response()->json(['success' => $user], Response::HTTP_OK);
}
}
I think you can refer to the solution below to solved you issue.
Laravel 7 filters
The guide lead you about how to setup Laravel Authentication which include at Laravel package.
You don't have to build out from scratch by yourself

User Signup with Laravel Passport - Password Grant

I know how the basic auth works for sign up/login on Laravel. However, I want to learn setting up how to do user sign up (for Password Grant). I set up Passport (2.0) - Passport Grant, and I can get token; however I couldn't find anything for user signup. Then I found a topic here explaining that I should call the oauth/token internally, but also couldn't figure out how to achieve it exactly.
So what I thought is creating a signup() method in a controller and handle user registration on my own, but then how would I pass necessary data to oauth/token route? Because what Laravel uses for $request is Request $request but what Passport uses is ServerRequestInterface $request and when I vardump the $request on oauth/token's issueToken method, it's totally different Request $request.
// Setup new method
public function signup(Request $request) {
// do validations
// create user
User::create([
'email' => $request->username,
'password' => bcrypt($request->password),
]);
$client = \Laravel\Passport\Client::where('password_client', 1)->first();
$oauthData = [
'grant_type' => 'password',
'client_id' => $client->id,
'client_secret' => $client->secret,
'username' => $request->email,
'password' => $request->password,
'scope' => null
]
// Here, I got confused how to pass this `oauthData` to `issueToken()` route
// and it takes it as `ServerRequestInterface $request`
}
Someone did it likes this here, but no idea how I should exactly implement this approach. Because my /oauth/token route's post method issueToken() is like this:
public function issueToken(ServerRequestInterface $request)
{
return $this->withErrorHandling(function () use ($request) {
return $this->server->respondToAccessTokenRequest($request, new Psr7Response);
});
}
I am very confused and couldn't figure out how to overcome this. What is the right way of handling such scenario where I need to signup users through api?

Laravel Refreshing JWT tokens

I have a small Lumen / Laravel app that is just used as an API. I am able to sign in and set JWT tokens but after a period of time they timeout, I was expecting them to refresh each time an Endpoint was hit.
I've been looking at the docs for Tymon's JWT-AUTH but I cannot seem to get it to work.
Below is an example of one of my end points which return an array of all the users in the db. But when the token timesout the endpoint returns the error You don't have previleges to view all users
I'd be very grateful if someone was able to advise me or show me how to make my code refresh a token when someone is hitting an endpoint.
Inside Controller
public function index(Request $request)
{
$user = JWTAuth::parseToken()->authenticate();
if (!$user->isAdmin()) {
return $this->error_respond(['error' => "You don't have previleges to view all users"]);
}
$users = $this->repository->findAllWithPlan();
return $this->respond(['users' => $users]);
}
Inside Routes.php
$app->group(['middleware' => 'jwt.auth'], function ($app) {
/**
* Show All users
*/
$app->get(
'users',
[
'as' => 'user.all',
'middleware' => 'cors',
'uses' => 'App\Http\Controllers\UserController#index'
]
);
});

Categories