I am creating laravel API based application where I used passport for authentication. I have also used the laravel socialite for social media login. The things are working fine with laravel passport but I am unable to verify the social medea token, Like we pass the google token in the header of every request but not getting the way to check the token validity in every request.
Is there anyone who can help me with this problem?
Thanks in advance.
You can check on middleware:
Middleware File:
class ApiAuthenticate {
public function handle($request, Closure $next)
{
$status = false;
$accessToken = $request->header('AccessToken');
if($accessToken) {
$user_check = User::where("api_token", $accessToken)->first();
if(count($user_check) > 0)
{
$status = true;
}
}
if($status == false) {
return response()->json([
'code' => 401,
'msg' => trans('web_service.unathenticated')
]);
} else {
return $next($request);
}
}
}
Route File:
Route::group(array('prefix' => 'api', 'middleware' => 'api'), function()
{
Route::get('/users', 'Api\UsersController#getUser');
Route::post('/users/save', 'Api\UsersController#saveUser');
})
Related
Im making a gym app on laravel 9 as an api. The app will have a normal user and also an admin which has access to certain files that a normal user doesnt. For that i created a middleware but im facing a few problems there.
See even after i log in, when i try using a route protected by my isAdmin middleware, i get the error: Log in to gain access. This is the Login function:
public function login(Request $request)
{
$creds = $request->validate([
'email' => 'required|email|string|exists:users,email',
'password' => ['required']
]);
if (!Auth::attempt($creds)) {
return response([ 'message' => 'Provided email or password is incorrect' ], 422);
}
/** #var \App\Models\User $user */
$user = Auth::user();
Auth::login($user);
$token = $user->createToken('main')->plainTextToken;
return response(compact('user', 'token'))->header('Authorization', 'Bearer '.$token);
}
and then this is the middleware
public function handle(Request $request, Closure $next)
{
if (Auth::check()) {
$user = Auth::guard('auth')->user();
dd($user);
if ($user->role == 1) {
return $next($request);
} else{
return response(['msg'=>'You are not authorized for this route!']);
}
} else{
return response(['msg'=>'Log In to gain access!']);
}
return $next($request);
}
Im pretty sure the problem has to do with the token either not being sent or being stored properly, but i cant seem to find where the problem is. Also this is what im doing in Postman if that would help:
Login
Add Recipe (this is a route guarded by the middleware)
And also here are their headers respectively
Also i dont know if this is info that will help but i have to manually write the that bearer token for it to show up. (im a beginner so idk how it should be done)
Can anyone help me to handle API route with optional Auth check? I have an API ROUTE 'apply-coupon' which can be used by both 'Guest' and 'Logged In' user. I need to get User ID in controller if the user is logged in.
Front end - Is developed with React JS, on 'Apply Coupon' button click, an API is calling as -
API end point - https://example.com/api/apply-coupon
Request payload - {coupon : 'my-coupon-code', shop_id : '1', subtotal : '150'}
Note : No token is passed in the header, since 'apply coupon' feature is available for guest user as well.
Expected output :- When user clicks on 'Apply Coupon' it should return User ID, if user id logged in.
Following is my route in api.php file -
Route::post('/apply-coupon', [
'uses' => 'CouponController#applyCoupon',
]);
Update :- And the default guard is -
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
I have tried
if(Auth::user()) {
dd(Auth::user());
}
and
auth()->guard('api')->user()
But nothing worked. Thanks!!
I don't think you can "optionaly" protect routes. What I think you could do is check in your controller if the user is authenticated and if it is, then get its ID. Of course the route should be unprotected
use Illuminate\Support\Facades\Auth;
...
function applyCoupon() {
if (Auth::check()) {
// The user is logged in...
// return Cupon + Auth::id()
} else {
// Not logged in code
// return Cupon
}
}
docs
Add one middleware ValidateUser.php
namespace App\Http\Middleware;
use Closure;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Tymon\JWTAuth\Exceptions\TokenInvalidException;
use Tymon\JWTAuth\Facades\JWTAuth;
class ValidateUser
{
public function handle($request, Closure $next)
{
if (! $request->bearerToken()) {
return $next($request);
}
return $this->validateToken($request, $next);
}
private function validateToken($request, Closure $next)
{
try {
if (! JWTAuth::parseToken()->authenticate()) {
throw new \Exception('Unable to find the account');
}
} catch (TokenExpiredException $e) {
throw new \Exception('Token has been expired');
} catch (TokenInvalidException $e) {
throw new \Exception('Token is not valid');
} catch (JWTException $e) {
throw new \Exception('Unable to parse the token');
}
return $next($request);
}
}
In your http/kernel.php in
$routeMiddleware
add
'api.auth.validate' => \App\Http\Middleware\ValidateUser::class
Now in your api.php you can use middleware to check it something like:
middleware(['api.auth.validate'])
(I'm aware that the following example isn't safe)
I have a basic authentication system where a user has to enter his credentials. When the entered credentials are correct I set in my laravel application a session, which indicates that he can perform authenticated requests to the api. I do that the following way:
public function authenticate(Request $request){
$data = array(
'name' => $request->input('UserName'),
'password' =>$request->input('Password'),
'email' => 'test#test.ch'
);
If(Auth::attempt($data)){
$request->session()->put('isAuthenticated',true);
$request->session()->save();
return "success";
}
return "wrong";
}
My middleware where I check if the user is allowed to make requests:
public function handle($request, Closure $next){
if(!empty($request->session()->get('isAuthenticated')) && $request->session()->get('isAuthenticated') === true){
return $next($request);
}
return redirect('/');
}
My routes:
Route::post('/login', 'UserController#authenticate');
Route::group(['middleware' =>['web','check_auth']], function (){
Route::get('/logs','LogController#getAllLogEntries');
Route::get('/logs/{id}','LogController#getLogEntryById');
});
My problem:
Whenever a user logs in with the right credentials the server returns "success" as response, but always directs me back to the base root ('/'). That makes me assume that the session doesn't get set. How can I fix this error?
How am I able to maintain or create a session through Ajax login. I have a Laravel installation not that much different from a basic make:auth installation.
I had to ovewrite some parts of the authcontroller to return json instead of redirects. Here's the login part:
/**
* Handle an authentication attempt.
*
* #return Response
*/
public function login(Request $request)
{
$this->validate($request, [
$this->loginUsername() => 'required',
'password' => 'required'
]);
// If the class is using the ThrottlesLogins trait, we can automatically throttle
// the login attempts for this application. We'll key this by the username and
// the IP address of the client making these requests into this application.
$throttles = $this->isUsingThrottlesLoginsTrait();
if ($throttles && $this->hasTooManyLoginAttempts($request)) {
// to many attempts
if ( $request->ajax() )
{
$this->response['code'] = 406;
$this->response['message'] = $this->sendLockoutResponse($request);
return response()->json($this->response);
}
return $this->sendLockoutResponse($request);
}
$credentials = $this->getCredentials($request);
$credentials['is_active'] = 1;
if (Auth::attempt($credentials, $request->has('remember'))) {
// succes
return $this->handleUserWasAuthenticated($request, $throttles);
}
// If the login attempt was unsuccessful we will increment the number of attempts
// to login and redirect the user back to the login form. Of course, when this
// user surpasses their maximum number of attempts they will get locked out.
if ($throttles) {
$this->incrementLoginAttempts($request);
}
// error
if ( $request->ajax() )
{
$this->response['code'] = 406;
$this->response['message'] = $this->getFailedLoginMessage();
return response()->json($this->response);
}
return redirect()->back()
->withInput($request->only($this->loginUsername(), 'remember'))
->withErrors([
$this->loginUsername() => $this->getFailedLoginMessage()
]);
}
/**
* Handle an authenticated response.
*
* #return Response
*/
public function authenticated($request, $user)
{
if ( $request->ajax() )
{
$this->response['message'] = "success";
return response()->json($this->response);
}
else
{
return redirect()->intended($this->redirectPath());
}
}
Here are the routes used:
Route::group(['namespace' => 'Auth'], function() {
Route::post('/login', ['uses' => 'AuthController#login', 'as' => 'login']);
Route::post('/registreer', ['uses' => 'AuthController#postRegister', 'as' => 'register']);
Route::post('/reset', ['uses' => 'PasswordController#sendResetLinkEmail', 'as' => 'reset']);
});
I am working with Vue.js in the frontend which get the error and succes responses perfectly. Only after refreshing the browser i am not in a logged in state. How am I able to do this.
There's no session when you are working with AJAX / JSON REST APIs. Instead of sessions, REST APIs use tokens / some kind of authentication.
If you are building a REST API and using VueJS as the front end framework for a single page application, use the api middleware instead of the default web middleware.
Read more information about JSON Web Tokens here:
https://jwt.io/introduction/
You are basically creating a stateless application when you are using Ajax. The frontend side basically didnt need to know the state of the user, wether he is already login or not. So you didnt need any session.
What you need to do is get information from the server wether your user is authorized to get any resource on the server. This is basically Authenticating (the process to validate user credential that being sent to the server and then returning sort of id to the user) and Authorization the process to check wether the id is authorized to access the resource requested.
I guess i declared my question not properly because of the misunderstandings. However i did get it to work. The fix is to put middleware around the specific routes. Now I am to login trough a Ajax request.
Route::group(['middleware' => 'web'], function () {
...
});
I have been trying to implement the JWT-Aut in Laravel's Dingo API package, but I am stuck at users Login part, I have checked the official docs for auth but cant figure out, here is what I have done till now.
Protected the routes
Route::api(['version' => 'v1', 'protected' => true], function () {
Route::resource('users', 'UserController');
});
Added JWT auth provider in dingo/config
'jwt' => function ($app) {
return new Dingo\Api\Auth\JWTProvider($app['tymon.jwt.auth']);
}
Installed the JWT-Auth from Github docs
Tried Login using below sample code from JWT-Auth docs using Postman but getting {token : false}
Route::post('auth/login', function () {
$credentials = Input::only('email', 'password');
if ( ! $token = JWTAuth::attempt($credentials) )
{
// return 401 error response
}
return Response::json(compact('token'));
});
If someone can guide how I can login logout, & signup user and make a request with Authorization: Bearer <token> will be very helpful.
If someone could share your auth controller for same will be lifesaver :)
It looks like you are not returning a response when the credentials are incorrect - so the token will be equal to false in that case.
Here is an example:
Route::post('auth/login', function () {
$credentials = Input::only('email', 'password');
if ( ! $token = JWTAuth::attempt($credentials) )
{
// return the 401 response
return Response::json(['error' => 'invalid_credentials'], 401);
}
return Response::json(compact('token'));
});