Laravel Sanctum Vue.js - How to check if session is expired - laravel

I'm starting up a learning project with Laravel, VueJS. I'm using Sanctum cookie based.
I have got the authentication working with the help of several tutorials, but none of the tutorials covers the piece of checking if your session is expired or not. The tutorials that where covering it where using LocalStorage, and what I red about is that you should avoid LocalStorage.
I'm looking for a simple possibility to check if a user is still authenticated and if not, then redirect them to the login page, or even better, show a modal to login and go further where they are.
22 jan 2021 Still haven't got he answer :(
I'm fairly new to VueJS, Vuex and so on :)
Thanks for the help !

Try this, its what I've been using so far. Its not very ideal but works out fine so far until I can make it better.
Put this in App.vue created method
// each call needs csrf token to work, so we call this on app load once.
axios.get(axios.rootURL + '/sanctum/csrf-cookie').catch(() => {
alert('Something went wrong, Contact admin <br> ErrorCode: csrf')
})
// this part is not necessary, you may adapt as required
// let isLoggedIn = localStorage.getItem('isLoggedIn') ? true : false
// this.setIsLoggedIn(isLoggedIn)
axios.interceptors.request.use(
config => {
return config
},
error => {
return Promise.reject(error)
}
)
// this is the actual part you need, here we check on each call
// if we get error 401 which is unauthenticated we redirect to login. That's it
axios.interceptors.response.use(
response => {
return response
},
error => {
if (error.response.status === 401) {
this.$router.push({ name: 'login' })
localStorage.removeItem('isLoggedIn')
this.setIsLoggedIn(false)
}
return Promise.reject(error)
}
)

Related

Nuxt Auth + socialite manual login

I am trying to use the Nuxt Auth module and socialite for social logins. I have an API in Laravel 8 and a client in NuxtJS.
I am wondering if someone could tell me:
If my logic here is ok?
How to manually log user with nuxt auth (manually set token and user)?
So currently here is my flow for social logins:
Click on login with google makes an API call to my backend where I get redirect URL from socialite to google.
My frontend redirects me to the google login page, then back to my frontend app after I picked the account.
I send the google code to the backend to callback endpoint for socialite which then grabs me the google user. In same place after I deal with users in my app I am returning the token which I create by doing return $this->okResponse(['token' => $nativeUser->createToken('social-login')->accessToken]);
At this point I am back in my front end with the token which then I am trying to set this.$auth.setUserToken(response.data.token) which apparently does not equal logging the user in. So it looks like this:
mounted() {
this.$axios.get(`login/social/google/callback`, {params: {code: this.$route.query.code}}).then(response => {
console.log(response)
// this.$auth.strategy.token.set(response.data.token)
this.$auth.setUserToken(response.data.token)
if (this.$auth.loggedIn) {
console.log('I am logged in!')
} else {
console.log('I am NOT logged in!', this.$auth)
}
})
}
I am not logged in. Do I have to manually set loggedIn, 'User' and token? Or this is just madness? The only other thing I see here as a solution is my own custom strategy but this seems like total overkill.
Not sure if this is the best way but I ended up doing something like this.
mounted() {
this.$axios.get(`login/social/google/callback`, {params: {code: this.$route.query.code}}).then(response => {
this.$auth.setUserToken(response.data.token)
this.$auth.setUser(response.data.user)
if (this.$auth.loggedIn) {
console.log('I am logged in!')
} else {
console.log('I am NOT logged in!', this.$auth)
}
})
}
This seems to be working ok.

How to use Auth::check or Auth::user between different domains?

I've got a question regarding Laravel framework (vers. 5.2) and the authentication. I have 2 domains which represent a software. let's call them https://azure.mydomain.com and https://azuresoftware.mydomain.com.
The Laravel application is hosted on the domain https://azuresoftware.mydomain.com. https://azure.mydomain.com is just a CMS framework which is providing some information about the website.
Now I want to display different menus, if the user is logged in or not on https://azure.mydomain.com. I thought, I can do a fetch request to https://azuresoftware.mydomain.com/ and use the Laravel methods Auth::check() to check if the user is already logged in or not. I know that this is a CORS fetch request, but this is not the issue. I've allowed in the IIS webserver requests from https://azure.mydomain.com. The request works fine and also just a simple request. But actually Auth::check() is always returning false, even when I'm logged in on the software side.
This is my code so far:
<script>
fetch('https://azuresoftware.mydomain.com/checkLogin', {
method: 'GET',
headers: {
'Content-Type': 'text/plain'
}
})
.then(function(res) {
return res.json()
})
.then(function(data) {
if(data.isLoggedIn) {
// do some stuff...
}
else
{
// do some other stuff...
}
});
</script>
routes.php:
Route::group(['middleware' => 'web'], function () {
...
Route::get('checkLogin', function() {
return json_encode(['isLoggedIn'=>\Auth::check()]);
});
...
I'm sure, I forgot something essential, why it is not working this way.
This is due to the fact that AJAX calls only send cookies if the url you're calling is on the same domain as your calling script.
See Cross domain POST request is not sending cookie Ajax Jquery for more information.

laravel_token is valid for first request but not subsequent requests

I have installed Laravel Passport and configured it according to the documentation. When calling axios.get from my VueJS file, the first call works as expected. the laravel_session Request Cookie is injected into the request, and the authentication passes, returning the resource.
My problem arises when I try to call the axios.get method again. My use case here is a search function. I'm making a call to /api/banking/accounts/search/{search-term} whenever the user types into a text field, using the code below:
remoteMethod(query) {
if (query !== '') {
this.loading = true;
axios.get(
`/api/banking/accounts/search/${escape(query)}`
).then(res => {
this.destinationAccountDirectory = res.data;
this.loading = false;
});
} else {
this.destinationAccountDirectory = [];
}
},
This code works fine without any auth:api middleware on the route, and for the first time with auth:api middleware. As can be seen from the screenshots below, the laravel_token value changes and is rejected on subsequent calls to the API.
**I've tried to removed the \Laravel\Passport\Http\Middleware\CreateFreshApiToken that was added to the web middleware group during passport installation, which seemed to have temporarily solved the issue, until I receive a 419 on a request shortly after. What could be causing the new laravel_tokens to be rejected? **
I solved this by removing the web middleware from my API route. Why it was there in the first place, I have no idea.
I changed my api.php from
Route::group([
'middleware' => [
'web',
'auth:api']], function() {
Route::post('/banking/transactions', 'TransactionController#store');
Route::get('/banking/accounts', 'BankAccountDirectoryController#index');
Route::get('/accounts/{account}', 'BankAccountDirectoryController#show');
Route::get('/banking/accounts/search/{term?}', 'BankAccountDirectoryController#search');
});
to
Route::group([
'middleware' => [
'auth:api']], function() {
Route::post('/banking/transactions', 'TransactionController#store');
Route::get('/banking/accounts', 'BankAccountDirectoryController#index');
Route::get('/accounts/{account}', 'BankAccountDirectoryController#show');
Route::get('/banking/accounts/search/{term?}', 'BankAccountDirectoryController#search');
});
Should the API routes be under the web group to benefit from the middleware, or is it purely for UI? Am I safe to do this?

Symfony2 send back login form on each AJAX request

I'm doing a back-office image upload form using Symfony 2.5.12 (yeah I know I'm a little out of date, but I will work on that soon :)). I want to upload the images via AJAX, but I get a 302 redirect to the login form on every AJAX request I send.
Here is the JS part on my stuff (it is simplified because for the moment I just want to do a successful AJAX call without 302 redirect to the login page, so I deleted the data related stuff) :
form.addEventListener('submit', event => {
event.preventDefault();
const url = form.getAttribute('action'); // '/admin/uploadImage'
fetch(url)
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
});
And here is my action in my controller, bound to /admin/uploadImage URL :
public function uploadAction() {
return new JsonResponse(array('test' => 'hello world'));
}
Every /admin URL requires ROLE_ADMIN role, I defined it in security.yml :
security:
#...
access_control:
- { path: ^/admin, roles: ROLE_ADMIN }
This way, it is normal that a login form shows when I want to access to this kind of URL. But when I trigger my AJAX call, I'm already logged in because I'm on /admin/gallery page.
Does anybody can figure out what is wrong with what I'm doing ?
Thank you very much.
I absolutely don't know why, but it seems the issue was related to whatwg-fetch fetch implementation. I replaced it with axios and the problem is gone.

User Sessions Parse.com Cloud Code Hosting

My login form currently posts to itself on /
The post request is then picked up as follows...
app.post('/', userController.doLogin);
Then the controller is a follows..
exports.doLogin= function(req, res) {
Parse.User.logIn(req.body.username, req.body.password, {
success: function(user) {
console.log('login success');
res.render('loginSuccess');
},
error: function(user, error) {
console.log('login failed');
res.render('loginFailed');
}
});
}
This works correctly for a correct / incorrect login.
However, once logged in, the session is not stored no cookies are created / local storage etc..
Therefore when I test for login on one of my other routes it always displays as no-session, i am checking with the following code..
if(Parse.User.current()){
console.log('logged in and redirected');
res.redirect('/member/home');
}else{
console.log('not logged in, redirected to home/login page');
res.redirect('/');
}
Which always goes too home / again.
I read here https://parse.com/docs/hosting_guide#webapp-users that...
You just need to call Parse.User.logIn() in Cloud Code, and this middleware will automatically manage the user session for you.
Which would suggest it does the session for me?
Any help would be super useful! many thanks in advance!
Ok so after a lot of digging I have worked it out. First you need to add the module by doing the following..
var parseExpressCookieSession = require('parse-express-cookie-session');
Second you need to setup your own variables like this
app.use(express.cookieParser('YOUR_SIGNING_SECRET'));
app.use(parseExpressCookieSession({ cookie: { maxAge: 3600000 } }));
Third, you must do send the login/session all over HTTPS.
Boom, working - easy peasy when you know how.

Resources