Laravel rest api (santum) for mobile application - laravel

I have created a REST API with LARAVEL SANCTUM. I have tested api on postman and it works as expected but when mobile developer uses it on ionic app, it returns for login "TOKEN MISMATCH".
Here is my API route
Route::post('/register', [ApiController::class, 'register']);
Route::post('/login', [ApiController::class, 'login']);
Here is the ApiController for login
public function login(Request $request){
$fields = $request->validate([
'email' => 'required|string|email|max:255',
'password' => 'required|string|min:8'
]);
//validate login parameters
//check email
$user = User::where('email', $fields['email'])->first();
//check password
if(!$user || !Hash::check($fields['password'], $user->password)){
return response([
'message' => 'Invalid Credentials'
], 401);
}
$token = $user->createToken('myapptoken')->plainTextToken;
//return $user->createToken($request->device_name)->plainTextToken;
$response = [
'user' => $user,
'token' =>$token,
];
return response($response, 201);
}
EndPoint: https://findajob.ng/api/login
Email:johndeo1#gmail.com
Password: 12345678

This might not be a problem from backend, but in other-hand, if everything work in postman, you might try to:
Change support_credentials in config\cors to true.
Add withCredential header to front-end.

Related

Laravel sanctum and vue: user is logged in frontend but backend returns unauthorized

i have a log in form in my front end (vue) when users log in, in vue i can get back data of logged in user perfectly fine through
axios.get('http://127.0.0.1:8000/api/user').then((response)=>{
this.userData = response.data;
However in my backend when i try to bring back the logged in user though
if ($request->user('sanctum')) {
return "auth";
} else {
return "guest";
}
it returns guest i dont know why!!!!
vue code:
async login(){
axios.post('http://127.0.0.1:8000/api/login', this.form).then((response) =>{
localStorage.setItem('token', response.data);
axios.defaults.headers.common['Authorization'] = `Bearer ${response.data.token}`;
this.$router.push('/');
} )
.catch ((error) =>{
console.log(error.response.data.errors);
})
},
laravel auth controller :
public function loginn(Request $request){
$request->validate([
'email' => 'required',
'password' => '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("token")->plainTextToken;
return response()->json([
'token' => $token,
'type' => 'bearer',
'expires_in' => auth()->factory()->getTTL() * 60
]);
api.php
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});
Route::post('/signup', [authcontroller::class, 'signupp']);
Route::post('/login', [authcontroller::class, 'loginn'])->name('login');;
Route::post('/logout',[authcontroller::class, 'logout'])->middleware('auth:sanctum');
I haved this problem.
This problem is for .env in backend laravel and get csrf front
remembering that the localhost address must be either localhost or 127.0.0.1 amd get csrf before
axios.get('/sanctum/csrf-cookie').then(response => {
// Login...
});
.env
SESSION_DOMAIN=127.0.0.1
SACTUM_STATEFUL_DOMAINS=127.0.01:PORT

Laravel 9: Auth::user() / auth()->user() null after successfull login

I made a manual login system in a Laravel 9 API that it's works correctly, but when I try to use Auth::user() in another controller, I get it as null, but when I return the auth->user() to the Vue SPA, I get it correctly. Is there a way to it is setting Auth::user() null after a successfull login? Here's are my api.php (api routes):
route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});
route::controller(UserController::class)->group(function () {
route::post('/register', 'register');
route::post('/login', 'login');
route::get('/logout', 'logout');
});
route::resource('book', BookController::class);
route::get('/my_books/{user_id}', [BookController::class, 'myBooks']);
As you can see in the image above, I can get the authenticated user after try login it, here's my login method:
public function login(Request $request)
{
$validate = $request->validate([
'email' => 'required|email',
'password' => 'required'
]);
if ($validate) {
$credentials = $request->only('email', 'password');
return Auth::attempt($credentials)
? Auth::user() :
response()->json('No se ha podido iniciar sesiĆ³n', 500);
}
return response()->json($validate->errors, 422);
}
But when I'm going to store a new book, I get the following error:
Here's the error, when I try to use the auth()->user() method to get the logged in user's id:
public function store(Request $request)
{
$validate = $request->validate([
'title' => 'required',
'genre' => 'required'
]);
if ($validate) {
$book = Book::create([
'title' => $request->title,
'author' => $request->author,
'genre' => $request->genre,
'subgenre' => $request->subgenre,
'opinion' => $request->opinion,
]);
$user = User::find(auth()->user()->id);
if ($request->cover) {
$this->uploadImage($request, 'cover', $book);
}
$user->books()->save($book);
return new BooksResource($book);
}
I don't know why it's happening, and I'd like any idea or possible solution. Thanks in advance:
From laravel 9 documentation
// Get the currently authenticated user's ID...
$id = Auth::id();
Also, you should describe your
route::get('/my_books/{user_id}', [BookController::class, 'myBooks']);
route before resource route.
I guess, you dont need this assign $user = User::find(auth()->user()->id); just use auth()->user
To get the Authenticated user, put the book route inside the auth:sanctum middleware.

Laravel 8 connection at the web app with api

For my job, I have to make an app which never use the database directly. I have to only request an API even for the connection.
So... There is my problem. I try to make an auth with a user that i'm getting from API but i'm always redirect to the login page.
My API auth :
public function login(Request $request)
{
$credentials = request(['use_username', 'password']);
$this->guard()->factory()->setTTL(config('jwt.ttl') * 12);
if (!$token = $this->guard()->attempt($credentials)) {
return response()->json(['error' => 'Unauthorized'], 401);
}
$user = auth()->user();
return $this->respondWithToken($user, $token);
}
protected function respondWithToken($user, $token)
{
$cookie = cookie('jwt', $token, 60 * 12); // 12h
return response()->json([
'user' => $user,
'token' => $token
])->withCookie($cookie);
}
My web app auth :
public function login(Request $request)
{
$response = Http::post(env('app_url').'/api/auth/login', $request->only('use_username', 'password'));
$cookie = cookie('jwt', $response['token'], 60 * 12); // 12h
$user = ( new User() )->forceFill( $response['user'] );
if (Auth::login($user)) {
$request->session()->regenerate();
return redirect('/');
}
flash('error')->error();
return back()->withErrors([
'email' => 'The provided credentials do not match our records.',
]);
}
My API guard (default guard) :
'api' => [
'driver' => 'jwt',
'provider' => 'users',
'hash' => false
]
The goal is to authenticate the user in the API, get a JWT token and auth the user in the web app with the same user that got in the API. After, all my request to the API have to use the JWT token get during the login... Maybe with a HttpOnly cookie ?
Well, i can't connect my user to the web app, i'm always unauthenticate and redirect to th elogin form, can someone help me ?
I'm using tymon/jwt-auth library with PHP 8

Laravel Sanctum - getting 401 on auth:sanctum with token returned after login

I have the following login method:
public function index(Request $request)
{
$request->validate([
'email' => 'required|email',
'password' => 'required',
'device_name' => '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 response([
'user' => $user,
'session_token' => $user->createToken($request->device_name)->plainTextToken,
], 201);
}
This method is working and returning token is a format similar to this:
5|5lR3o7vEzlm6iOieKxTW2pco1msKLN0WHb0Ozxv2relwIB4eJetyPnADOu6Dp0griYY7U1YZJEAqk6Ct
When I try to use a route behind auth:sanctum with that token I am getting
401 - "message": "Unauthenticated."
I am using the latest Laravel 7. Configuration:
.env
APP_URL=http://localhost:9099
SANCTUM_STATEFUL_DOMAINS=http://localhost:9099
cors.php
'paths' => ['api/v1/*'],
I am using Insomnia for API testing. The login method works and also any route that doesn't use auth:sanctum middleware.
Any idea what am I doing wrong here?
Assuming you are running the server on port 9099 try setting your .env file to:
SESSION_DOMAIN=http://localhost
SANCTUM_STATEFUL_DOMAINS=http://localhost:9099
SANCTUM_STATEFUL_DOMAINS should be set the same as the url in your browser
I had my expiration set as null and I kept getting 401 errors. When I changed it to 60*24*30 it works.

Why is the request user null in my logout function?

I am implementing an Authentication api in Laravel using passport.
I have implemented the login api, but there is a problem with logout api. My login code is working successfully:
public function login(Request $request){
$request->validate([
'email'=> 'required|string|email',
'password'=> 'required|string',
'remember_me'=> 'boolean',
]);
$credentials= request(['email','password']);
if(!Auth::attempt(['email' => $request->email, 'password' => $request->password])){
return response()->json([
'message'=> 'Unauthorized'
],401);
}
Auth::attempt(['email' => $request->email, 'password' => $request->password]);
$user=$request->user();
$tokenResult = $user->createToken('Personal Access Token');
$token = $tokenResult->token;
if($request->remember_me)
$token->expires_at= Carbon::now()->addWeek(1);
$token->save();
return response()->json([
'access_token'=>$tokenResult->accessToken,
'token_type'=>'Bearer',
'expires_at'=>Carbon::parse($tokenResult->token->expires_at)
->toDateTimeString()
]);
}
This works successfully, however, when I use the same bearer token to revoke the token of the user I am receiving the following exception:
Call to a member function token() on null
This is referring to the first line of the logout method below.
public function logout(Request $request){
$request->user()->token()->revoke();
return response()->json([
'message'=> 'Successfully logged out'
]);
}
Why is the output of $request->user() null?
Create a token for the authenticated user, not the guest user who made the request
$user= auth()->user();
$tokenResult = $user->createToken('Personal Access Token');
$token = $tokenResult->accessToken;
And when revoking
public function logout(Request $request)
{
auth()->user()->token()->revoke();
return response()->json([
'message'=> 'Successfully logged out'
]);
}
Hope this helps

Resources