I am using #auth0/auth0-react library to handle authentication process. For an unauthorized user, it will redirect to back to initial screen ("/") route with this query params. ?error=unauthorized... Then again if I am trying to execute the login it will stay on the same page. Maybe I need to find a way to clear the previous auth0 state.
const { loginWithRedirect, logout} = useAuth0();
const loginWithAuth0 = () => {
logout({}); // clear previous auth 0 state
loginWithRedirect({
redirectUri: window.location.origin + "/dashboard"
});
};
Above is my attempt. Using logout({}) I am trying to clear the previous auth0 state and going forward which doesn't happen. For an authorized user there's no issues. So what I need is to handle the unauthorized user behaviour. Currently it will not redirect to the dashboard which is correct for unauthorized. But what I need is to clear the previous auth0 state and redirect to the next attempt. How can I achieve it?
You could destructure the isAuthenticated prop off of the object returned by the useAuth0() hook:
const { loginWithRedirect, logout, isAuthenticated } = useAuth0();
if (!isAuthenticated) {
logout({}); // (not certain this is necessary)
// redirect with whatever router your framework might include
}
Also consider the withAuthenticationRequired function which is exported from the same #auth0/auth0-react package, and allows you to protect a route/component and configure a redirect for unauthenticated users at the same time:
When you wrap your components in this Higher Order Component and an anonymous user visits your component they will be redirected to the login page and returned to the page they we're redirected from after login.
Related
In my nuxt project, i get a token from the backend that identifies the user. I tie this token to a vuex prop and save it in localstorage, so the user doesnt have to re authenticate when the page is refreshed.
To revalidate the user only when the page is actually refreshed, i wrote a beforemount function in the highest level, which is the default layout
beforeMount() {
const token = localStorage.getItem('user-token')
console.log(token)
if (token) {
this.$axios.defaults.headers.common.Authorization = token
this.$store.dispatch('auth/setToken', token)
}
}
In the next step, the router on protected pages should check if the authstate is true, which is only true if the vuex localstorage prop is set. Since i only need that on certain pages, i wrote a router middleware thats only loaded on these pages
export default function (context) {
if (!context.store.getters['auth/isAuthenticated']) {
return context.redirect('/auth?login')
}
}
Problem is, the middleware runs before the beforeMount according to the docu, which creates the problem that the middleware checks for a token which is set later and kicks the user out.
Since the only thing that comes before router middleware is global middleware, my plan was to write the reauth as global middleware. But somehow, the middleware is also called on every router change, not only before the site is created aka page refresh. This would execute the function way too often.
The goal is to set the token before the route validate based on the token, only on page refresh, since the rest is taken care of by vuex.
There are already many answers but I couldn't use them according to my scenario
in which my login component is a child component and i am using react-router-dom of 5.1.2 version
currently i am using local storage to save authToken but I know it is not a good approach. Where should I save the auth token then such that whenever someone tries to hit login route manually or by button they are redirected because token was expired
my route that i am currently using in app.js
<Route path={process.env.PUBLIC_URL + "/login-register"} component={(!isVerified)?LoginRegister:HomeFashion}/>
and this is the child component login
const login = async()=>{
try{
const options = {
username:username,
password:password
}
var response = await axios.post(CONFIG.url+'api/login',options)
localStorage.setItem("__user",JSON.stringify(response.data))
history.push({
pathname: '/',
// search: '?update=true', // query string
state: { // location state
user: response.data,
},
});
}catch(err){
isError(true)
}
}
React.useEffect(()=>{
if(location.state!==undefined){
setMsg(location.state.msg)
if(msg)
{
alert(msg)
}
}
},[location])
what i am doing is when i am successfully logged in i get token and user data in response form backend I store it in localStorage and redirects things according to it
what is the right way to do so?
I need to redirect our users to a SSO form that is handle by another team. This form (is not a next.js app) is on the same domain as the next.js app.
I try to follow https://nextjs.org/docs/authentication#authenticating-server-rendered-pages but I can't figure out on how to get the current URL, so I can tell the SSO to redirect back once authentication is finish.
return {
redirect: {
destination: `/sso/form?redirect=${currentUrl}`,
permanent: false,
},
}
Any idea, on how to get the currentUrl?
The context contain a property called resolvedUrl corresponding to the current route.
const { resolvedUrl, req } = context;
const baseUrl = getBaseUrl(req);
const currentUrl = `${baseUrl}${resolvedUrl}`;
getBaseUrl is an helper function that return the base url of our current nextjs app.
The redirection you are doing on the getServerSideProps is done in the server so no dom info can be accessed on that level. You have tu pass the path info to the server in a cookie or something like that.
Anyway, if im not mistaken, you redirect to SSO when you try to load a page and the auth fails. This auth happens on getServerSideProps so you can hardcode the SSO redirection url because you call a different getServerSideProps everytime you go to a new page.
I am attempting to implement 0Auth user authorization for my Next.js app using MoneyButton API. I am able to trigger the authorization request with client.requestAuthorization('auth.user_identity:read','http://localhost:3000');
And it works smoothly redirecting me to MoneyButton permission consent and back to my app with the code and state params in URL -> ?code=6aa72eef702eb710cd22715d797cf7d27e06532a&state=38984b9d-3af0-48f1-8b5f-3fa47f4dfd9d
There is client.handleAuthorizationResponse(); method for handle the response. That method automatically gets the tokens from the query parameters and set the internal state of the client to use them. Also it saves the credentials in local storage, so the user stays logged in with Money Button if they close the browser.
But unfortunately i don't know how to use this method after being redirected back to my app. I am using it in Authuser function, but requestAuthorization triggers redirect to moneybutton, so rest of the function is not executed. How to use handleAuthorization after being redirected back to application?
https://docs.moneybutton.com/docs/api/auth/api-auth-jsclient.html - here are the MoneyButton docs
I am also considering to add MoneyButton as custom 0Auth provider in NextAuth.js to make integrations faster in the future.
Authuser.js
const { MoneyButtonClient } = require('#moneybutton/api-client')
export default function Authuser () {
const client = new MoneyButtonClient('MYAPP_OAUTH_IDENTIFIER_CODE');
client.requestAuthorization('auth.user_identity:read','http://localhost:3000');
client.handleAuthorizationResponse();
const refreshToken = client.getRefreshToken();
client.setRefreshToken(refreshToken)
}
You need to make sure that client.handleAuthorizationResponse(); is run client side (not server side render) after the moneybutton auth has redirected back:
if ((new URLSearchParams(window.location.search)).has('code')) {
await client.handleAuthorizationResponse()
const accessToken = await client.getValidAccessToken()
...
}
I attempted to create a very simple redux middleware to handle the auth needs in my application. Users in this app can have 3 states:
unregistered (should always be redirected to login)
partially registered (should redirect them to a secondary login. Users need to belong to a group to access any features in the app. So after initial registration they need to create or join a group. OR if they leave their group they'll be in this state and will need to have any actions redirect them to this page until they join a new group)
fully registered, should have full access with no forced redirects until they log out or leave their group.
So I was thinking a simple solution would be to have middleware that checks the status code of any async actions and redirects accordingly. So maybe a 401 would trigger a redirect to to the login/signup page, /login, and a 422 would trigger redirect to the secondary registration, /register.
This is my basic set up so far:
import { browserHistory } from 'react-router'
export default function({ dispatch }) {
return next => action => {
const url = window.location.href.split('/')
const location = url[url.length - 1]
if (location === 'login' || location === 'registration') {
return next(action)
}
let status;
const token = localStorage.getItem('token')
if (action.payload) {
status = action.payload.status
}
if (status === 401) {
return browserHistory.push('/login')
} else if (status === 422) {
console.log('redirect to registration')
return browserHistory.push('/register')
}
return next(action)
}
}
Obviously this approach does not utilize any higher order components for auth like most react/redux auth examples use. It seems to work OK, but I see a view start to render for a split second before a redirect so it isn't 100% smooth.
Is there a more efficient / simple way to handle this three state auth system? I am using react-router-redux.