Callback Error Handling #1603
Replies: 14 comments
-
Along these lines, if there's a server side error during code challenge verification (e.g. "code_verifier does not match the code_challenge") then I'd like to show that to the user. However, this is even less possible than what I wrote above, since at least with the callback page I could access the page's params in the URL. There's no way to get Auth's response from the server, so there's nothing I can return from my server to the client that will be accessible. |
Beta Was this translation helpful? Give feedback.
-
I have the same problem, I get a 400 from the backend if the email is already registered and it seems like there is no way to intercept this and show an error... Did you find a workaround for this @bmulholland? |
Beta Was this translation helpful? Give feedback.
-
No workaround; this will require we add error handling to the module. If you have thoughts on what you'd like that to do, and/or how you'd like it to work, that would help as I think about the design. Or feel free to submit a draft PR with some ideas, too :) |
Beta Was this translation helpful? Give feedback.
-
I'm not sure if it is possible with the redirecting etc, but the most elegant solution would certainly be a catch on the login, just like for the 'local' strategy: this.$auth
.loginWith('facebook')
.catch(error => ...) I found a way to intercept the error btw, but it is in the plugin and not on the page, which limits the reaction quite a lot. But better than nothing for now: // auth.js plugin
export default function({ app, route, $auth }) {
if ($auth.error) {
if (typeof alert !== 'undefined') {
alert(...)
}
// Remove query params to avoid errors when reloading the page and
// attempting another login action.
app.router.replace({ path: route.path })
}
} |
Beta Was this translation helpful? Give feedback.
-
Nice find, thanks for posting. You're right that the catch won't work because of redirects. I think we'll need an approach conceptually similar to what you have there - a defined error handling function at the configuration/plugin level. This is something I'll need for my own app in the next few months so I'll put some design into it then. |
Beta Was this translation helpful? Give feedback.
-
Thanks so much @bmulholland ! |
Beta Was this translation helpful? Give feedback.
-
The |
Beta Was this translation helpful? Give feedback.
-
Has anyone found any work-arounds for this? I'm particularly interested in handling the case when the callback URL is called with a server error. At the moment, as @bmulholland mentioned, the user gets stuck on the callback page. |
Beta Was this translation helpful? Give feedback.
-
Also run into this issue. I think, there is a flaw in the setup. As others pointed out, the runtime will call
|
Beta Was this translation helpful? Give feedback.
This comment was marked as spam.
This comment was marked as spam.
-
No, and asking for updates isn't going to make anything happen. Please don't do that. If you'd like to make progress on this, please write up a proposal of how we should implement it. What's the API? What code would change? Or even a PR with a sample implementation for discussion would be welcomed. That would do much more to get what you want :) |
Beta Was this translation helpful? Give feedback.
-
i tried to use |
Beta Was this translation helpful? Give feedback.
-
Yep, that's right, as stated in the OP |
Beta Was this translation helpful? Give feedback.
-
I have solved this problem using $store and axios interceptor. In short, we have to catch an error in the interceptor, send error information to $store and handle an error. For example, show an error and redirect to the sign-in page. I set an OAuth redirect page example.com/login and created it. pages/login/index.vue <template>
<div>Loading...</div>
</template>
<script>
export default {
name: "index",
layout: 'empty',
computed: {
error(){
return this.$store.getters['pages/login/get_error']
},
errorText() {
return this.$store.getters['pages/login/get_error_text']
}
},
methods: {
raiseError() {
this.$router.push('/sign-in') // redirect back to the sign-in page
this.$toast('error', this.errorText) // show an error with toast
}
},
watch: {
error(){
if (this.error === true) {
this.raiseError()
}
}
},
mounted() {
if (this.error === true) {
this.raiseError()
}
}
}
</script>
<style scoped>
</style> As you can see, I use mounted() and watch simultaneously to ensure I catch an error from store, despite google/backend speed, etc. Maybe it's excessive. Then create a simple $store for keeping error's information store/pages/login.js export const state = () => ({
error: false,
errorText: null
})
export const mutations = {
SET_ERROR(state, value) {
state.error = value
},
SET_ERROR_TEXT(state, value) {
state.errorText = value
}
}
export const getters = {
get_error(state) {
return state.error
},
get_error_text(state) {
return state.errorText
}
}
export const actions = {} And my interceptor looks like plugins/api.js import loadApi from '~/api'
function error400handler(store, e) {
if (e.config.url.includes('/api/social-login/google/')) {
store.commit('pages/login/SET_ERROR_TEXT', e.response.data.non_field_errors[0])
store.commit('pages/login/SET_ERROR', true)
}
}
export default ({ app, store, redirect }, inject) => {
app.$axios.interceptors.response.use(function (response) {
return response;
}, function (error) {
switch (error.response.status) {
case 400:
error400handler(store, error)
break
// there are other cases handling
}
return Promise.reject(error);
});
inject('api', loadApi(app.$axios, store))
} Since store works great in Nuxt plugins, this solution is able to resolve the problem with OAuth errors' handling. |
Beta Was this translation helpful? Give feedback.
-
Version
v4.9.1
Reproduction link
https://nuxt-auth.herokuapp.com/callback?error=access_denied&error_description=The%20user%20has%20denied%20your%20application%20access.&error_uri=https%3A%2F%2Fdocs.github.com%2Fapps%2Fmanaging-oauth-apps%2Ftroubleshooting-authorization-request-errors%2F%23access-denied&state=mk-asdfasdf
Steps to reproduce
If something goes wrong with OAuth, or the user clicks "cancel" partway through, they are redirected to the callback page and no error mechanism is available.
onError
isn't thrown, and there's no built-in convenience methods to deal with this. The error is not displayed on the page, and the nuxt error page is not displayed. The code just bails:auth-module/src/schemes/oauth2.ts
Line 345 in 5772ccb
Digging through the code, it does seem that fetchUser is called in this situation, and it would /seem/ like callOnError should be called as a result:
auth-module/src/core/auth.ts
Line 155 in 6ab4c1e
However, in this case, oauth2 just returns outright, which is not an error to be caught, and so it all falls right through.
The demo app is affected by this bug: https://nuxt-auth.herokuapp.com/callback?error=access_denied&error_description=The%20user%20has%20denied%20your%20application%20access.&error_uri=https%3A%2F%2Fdocs.github.com%2Fapps%2Fmanaging-oauth-apps%2Ftroubleshooting-authorization-request-errors%2F%23access-denied&state=mk-asdfasdf
What is expected ?
I'd expect there to be some way to handle these types of errors. Probably a hook for receiving the error message, and probably a redirect - to home or login page or error page.
What is actually happening?
User sees endless spinner and there's no built-in way to catch it.
Additional comments?
This seems like it should be core functionality? Am I missing something?
Beta Was this translation helpful? Give feedback.
All reactions