Auth0 with Vue not staying logged in after refresh on mobile devices - javascript

I am using Auth0 with a Vue application. Auth0 is acting strange and I have no idea where to begin.
If I am on a computer, then when switching pages in my app, the user gets logged out for a few seconds, the page loads and then Auth0 "loads" and logs the user back in. This is not desirable since it takes a few seconds to load up certain data on the page that only a user who is logged in should be able to see.
But this is my main problem:
On mobile devices, the user gets logged out when navigating to a new page within the app but the user never gets logged back in. Same thing happens when I refresh the page. The user gets logged out and I have to click the login button again.
Can't I make Auth0 work more efficiently where the user is immediately logged in when switching pages or never logged out in the first place?
This is all of my relevant code:
This is where Auth0 is imported into the app in main.ts:
import { createAuth0 } from "#auth0/auth0-vue";
app.use(
createAuth0({
domain: 'SOME_DOMAIN.auth0.com',
client_id: 'SOME_ID',
audience: 'SOME_AUDIENCE',
redirect_uri: window.location.origin,
scope: 'openid'
})
)
And then in each of the components that need to check if a user is logged in, I have this code:
import { useAuth0 } from '#auth0/auth0-vue'
// only showing relevant code here
setup() {
const { user, isAuthenticated, getAccessTokenSilently } = useAuth0()
return {
user,
isAuthenticated,
getAccessTokenSilently
}
}
And this is pretty similar code here but this is in the header component (rendered on every single page in the app) and contains the login/logout buttons:
setup() {
const { user, isAuthenticated, getAccessTokenSilently, loginWithRedirect, logout } = useAuth0()
return {
user,
isAuthenticated,
getAccessTokenSilently,
login: () => {
loginWithRedirect();
},
logoutUser: () => {
logout({ returnTo: window.location.origin })
}
}
},
So what am I missing? I need Auth0 to be more persistent. Am I missing some code?
Edit: not sure if this is important but this is how I navigate from one page to another:
router.push({ path: `/place/${store.selectedListView?._id}` })

I'm dealing with a similar problem using auth0 with react running on localhost. When I log in using loginWithRedirect(), auth0 places cookies on my browser but they would be cleared when I refresh the browser.
One solution to this was to enable 3rd party cookies for the localhost domain by going to browser settings, privacy and security, cookies and other site data, in "Sites that can always use cookies", add "http://localhost" and enable third party cookies for this site. This would let me stay logged in after reloading/refreshing.
However, I'm pretty sure there is a way to make this work without 3rd party cookies. I'll post it if found.

Related

Paladin Authentication Login issue through UI Cypress Automation

I'm new to Cypress and facing an issue while trying to login to my application from the UI(Application uses Paladin Authentication). After entering the username and clicked next button to enter the Password the web page shows an error as:
"Something went wrong.
Cookies may be disabled: Check your browser settings to ensure that cookies are enabled.
System clock may be misconfigured: Be sure that your system clock is correct.
Session may be expired: Close this window and try again."
When trying to manually login to the application from the same browser there are no issues.
i have tried some code to preserve the cookies in case the cookies are cleared in cypress ,not sure whether they are working.
Code im using to Login:
HPCustomerLogin()
{
const gmailid="gmail"
const password="password"
Cypress.Cookies.debug(true)
cy.visit('https://dcmcportalstg3.corp.hpicloud.net/#/MgtSMCHome')
cy.wait(3000)
//Cypress.Cookies.debug(true, { verbose: false })
cy.get('#app-login').shadow().contains('Use this login if you are HP Customer').next('button').click()
cy.wait(20000)
Cypress.Cookies.defaults({
preserve: (cookie) => {
return true;
}
})
Cypress.Cookies.defaults(
{
preserve: ['ASP.NET_SessionId', '__cypress.initial','CSRF-TOKEN','connect.sid','aka_client_code','autoredirect','SST-staging']
})
cy.get('#username').type(gmailid+'{Enter}');
cy.wait(3000)
cy.get('#password').type(password+'{Enter}');
cy.wait(15000)
}

Using keycloak in Vue3, but not on startup

I have a problem with keycloak.js in my Vue3 application
const keycloak = Keycloak(keycloakOptions)
keycloak.init({
onLoad: 'login-required',
checkLoginIframe: false
}).then(async (auth) => {
if (!auth) {
window.location.reload()
} else {
const app = createApp(App)
app.provide(process.env.VUE_APP_KEYCLOAK_PROVIDE_VARIABLE, keycloak)
app.use(store)
await store.dispatch('keycloakStore/fillRoles', keycloak.realmAccess.roles)
app.use(router)
app.mount('#app')
}
}).catch((e) => {
console.log('Serwer lezy: ' + e)
})
I have the above code in my main.js file. This runs the keycloak subpage with login/register. If someone succesfully logs in, my Vue app starts. Now, instead of the above, I’d like to make it so the Vue app starts regardless of the person being logged in and the keycloak screen is ONLY launched if someone clicks a specified button in the UI. I’ve searched examples on the net, but i can only find ones that run keycloak on application start. Can someone help?
Turn onLoad value from 'login-required' to 'check-sso'. This option will only verify if the user is logged in without redirecting the user to login, and setup authentication properties acordingly.
Then you can call keycloak.login(), for example in your code. Together with route guards if necessary.
Also, put the creation of the app out of the else block, because it will not load if the user is not logged in when you have 'check-sso'.

Is it possible to use session cookies in Firebase to stay logged in without firebase-admin package?

I'm using firebase in my next.js app to login. My login works but logs out every time a user changes paths inside the site. Once logged in, the user is redirected to the front page with path=/ if a user changes paths to path=/question/page firebase immediately logs them out but their session cookie has not expired. I would like to use the session cookie to keep a user logged in until it expires no mater where they navigate on the site. I am not about to use the package firebase-admin because it keeps crashing my next.js site. I can only use the regular firebase package which includes firebase.auth() along with js-cookie package. Here is the code I am using to set my cookie:
componentDidMount() {
let user = firebase_auth.currentUser;
console.log("User: ", user);
if (user) {
this.setState({user_logged_in: true});
return firebase_auth.currentUser.getIdToken(true).then(function (token) {
Cookies.set('__session', token, {expires: 7});
})
}
else {
this.setState({user_logged_in: false})
}
}
How would I be able to use the session cookie being called in the code above so that my users aren't being logged out every time they navigate to a new path?
Thanks for your help in advance!
Firebase Authentication SDKs automatically persist the user state between page/app reloads, and try to restore that state upon the restart.
The most likely cause of your problems, is that Firebase is still checking whether the authentication state is valid when you access firebase.auth().currentUser.
In that case, the solution is to use an auth state listener:
componentDidMount() {
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
this.setState({user_logged_in: true});
firebase_auth.currentUser.getIdToken(true).then(function (token) {
Cookies.set('__session', token, {expires: 7});
})
} else {
this.setState({user_logged_in: false})
}
});
}

NuxtJS and Auth Route Exemptions

I'm current using Nuxt.js and the authentication module it comes with.
Is it possible to create exemptions in auth to prevent automatic redirection to the login page when a user is not logged in?
Take the following as an example:
User is not logged in and navigates to: http://localhost:3000/#/password-reset
They will be redirected to the login screen: http://localhost:3000/#/login
I want to create an exemption so that all routes are protected by auth, which they already are, with the exception of the page to reset passwords (http://localhost:3000/#/password-reset).
How is this possible?
I assume your are using nuxt-auth.
Create a middleware middleware/isAuth.js:
export default function({ app, error }) {
if (!app.$auth.loggedIn) {
// If you want to redirect to login page
app.router.push('/password-reset')
// If you want to throw error, use this:
return error({
statusCode: 403,
message: 'You are not allowed to see this'
})
}
}
In page you want to protect, declare your middleware:
export default {
...
middleware: ['isAuth'],
...
}
It will prevent page if user is not logged in.
To log user, you should use loginWith.

Authentication logic for sessions that last while tab is open

Assume you are working on a front end application that performs authentication through 3rd party api. Successful authentication returns a json web token.
What would be best practices to store such token and create some sort of session for user while he is active on the website i.e. didn't close a tab or browser, however refreshing / reloading a page should not destroy such session.
Also, how can this session be used to protect routes? I am working with a stack consisting of react / redux / node / express and quiet a few other libraries. I believe I can perform certain checks within my react-router, however wouldn't it be better to do these on the express side?
You can store the token in localStorage or sessionStorage, and include it in every API request.
Local storage outlives the tab, it's stored there until you explicitly delete from it, so refreshing a page won't be a problem. Even closing a tab and then coming back won't be.
Session storage allows you to store data. Page refreshes are fine, but tab closing isn't, which is closer to the behavior you want.
As for protecting routes, the server should obviously check the token on requests to all protected API routes.
On the browser side, you will probably want to show a login form if a user tries to visit a protected route but the token isn't there (or is invalid).
With react-router, you could do it like the official repo shows in the example, via onEnter hooks: https://github.com/reactjs/react-router/blob/master/examples/auth-flow/app.js
An alternative would be to create two top-level components, one for protected routes, one for public routes (like a landing page or the sign in/sign up forms). The protected handler will then in componentWillMount check if there's a token:
- PublicHandler
+ SignIn
+ SignUp
+ Index
- ProtectedHandler
+ Dashboard
+ MoneyWithdrawal
it may looks like that , with sessionStorage (JWT token is accesseble, untill browser or tab closed)
///action creator redux
export const signupUser = creds => dispatch =>{
dispatch(requestSignup());
return API.auth.signup(creds)
.then(res => {
sessionStorage.setItem('token', res.token);// <------------------
dispatch(receiveSignup(res));
return res;
})
.catch(err => {
dispatch(SignupError(err));
);
});
};
On client : handling auth through HOC redux-auth-wrapper
On server on server you can use passport-jwt strategy
passport.use('jwt',new JwtStrategy(opts, function(jwt_payload, done) {
User.findOne({where:{ id: jwt_payload.user.id }}).then(user=>{
if (user) {
done(null, jwt_payload.user);
} else {
done(null, false);
// or you could create a new account
}
},err=>{
console.log('Error ',err);
return done(err,false);
});
}));
then just add route handler
var checkJWT = passport.authenticate('jwt')
router.get('/protected',checkJWT, (req, res) =>{
res.json(req.user);
});
You don't need sessions on server for that

Categories

Resources