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";
Related
I am using the Laravel socialite package to integrate Facebook login. But when a new user logs in using a Facebook account sometime its redirects to the correct page but sometimes it redirects to the Facebook home page. But it should be redirected to the application dashboard.
I couldn't figure out the exact issue.
My callback URL is like this
https://example.com/auth/facebook/callback
public function redirect()
{
return Socialite::driver('facebook')->redirect();
}
public function callback()
{
$facebook_user = Socialite::driver('facebook')->stateless()->user();
}
In the callback method, you can login and redirect like this (only for example):
public function callback()
{
$facebook_user = Socialite::driver('facebook')->stateless()->user();
$user = User::updateOrCreate(['facebook_user_id' => $facebook_user->getId()], [
'name' => $facebook_user->getName(),
'email' => $facebook_user->getEmail(),
'password' => Hash::make('test'),
'status' => strval(Status::active)
]);
Auth::loginUsingId($user->id);
return redirect()->route('your-user-dashboard');
}
see also: https://laravel.com/docs/9.x/socialite#authentication-and-storage
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
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.
I have a working password reset process with the following routes:
Route::group(['middleware' => [], 'namespace' => 'Auth'], function () {
Route::get('/password/reset/{token?}', ['as' => 'site.password.showResetForm', 'uses' => 'PasswordController#showResetForm']);
Route::post('/password/email', ['as' => 'site.password.sendResetLinkEmail', 'uses' => 'PasswordController#postEmail']);
Route::post('/password/reset', ['as' => 'site.password.reset', 'uses' => 'PasswordController#reset']);
});
My problem arises if someone is currently already logged in on the machine. In that case when A user clicks on the link in the email, PasswordController#showResetForm is never executed and the their home page opens in a new tab. Is there a way to force the current user to be logged out so that the password reset can proceed?
Call Auth::logout(); in one of your controllers.
If the showResetForm is never displayed due to user being logged in, you will need to create a temporary page where you call the above function and then redirect to Password Reset page:
public function do_password_reset()
{
Auth::logout();
return redirect()->route('PasswordController#showResetForm');
}
(Remember to add the relevant route for this function.)
Rather than creating additional routes I overwrote the showResetForm function used to route the user to the auth.password.reset view, found in
vendor/laravel/framework/src/Illuminate/Foundation/Auth/ResetsPasswords.php
To do so, within your ResetPasswordController add the following:
public function showResetForm(Request $request, $token = null)
{
$this->guard()->logout();
$request->session()->flush();
$request->session()->regenerate();
return view('auth.passwords.reset')->with(
['token' => $token, 'email' => $request->email]
);
}
All being well that should be the only code you need to add.
As for editing the ResetPasswordController suggested by Lawrence, you might want to remove guest middleware from it's constructor:
$this->middleware('guest');
This middleware redirects authenticated uses to the root page, so it would prevent an already logged in user from logging out.
I am writing a Laravel 5.2 application. I need to manually login the user for which I am using \Auth::login($user). I am doing it in following way.
if ($user = User::where('phone',session('phone'))->first())
{
\Auth::login($user);
// \Auth::loginUsingId($user->id);
// Auth::attempt(['email' => $user->email, 'password' => 'password']);
$data = \Auth::user(); //returning correct results
}
I have tried all the options namely Auth::login($user), Authh:loginUsingId($user->id) and attempt method. These methods are working fine as the $data variable is storing the object of correct user. But the problem is when I move to other route say '/home' the user remain no more authenticated.
What might be the wrong here? How could I do it correctly?
Since Laravel 5.2, you have to attach all your routes that need session with the 'web' middleware. See your app/Http/Kernel.php, the 'web' middleware contains the \Illuminate\Session\Middleware\StartSession.
In routes you have to use web in laravel 5.2
Route::group(['middleware' => ['web', 'auth']], function () {
Route::get('/', 'HomeController#index');
Route::get('/profile', 'HomeController#profile');
});