I'm very new to both nuxt and auth0. I'm using auth0 with my nuxt app and I have written a piece of code in my main pages mounted hook that enables me to login to the server when I use $auth.login() then it returns me to my app and gives me a token in the url. I can get my user profile's info using the token with /auth/me in my mounted hook but when I log $auth.$state it says you're not logged in:
loggedIn: false
strategy: "auth0"
user: null
How can I use $auth object with my auth0 code?
This is my nuxt.config.js:
auth: {
redirect: {
login: '/',
callback: '/auth/signed-in'
},
strategies: {
local: false,
auth0: {
domain: process.env.AUTH0_DOMAIN,
client_id: process.env.AUTH0_CLIENT_ID,
}
}
},
Related
I am using nuxt-auth with google oauth2 config, here is my nuxt.config.js config:
auth: {
scopeKey: 'scope',
strategies: {
google: {
client_id: process.env.GOOGLE_KEY,
codeChallengeMethod: '',
scope: ['profile', 'email'],
responseType: 'token id_token'
}
},
redirect: {
login: '/login',
logout: '/logout',
home: '/',
callback: '/welcome'
}
},
router: {
middleware: ['auth']
},
I use this code to login
this.$auth.loginWith('google')
I want to setup a role for user (visit app database) after successful login, so I added this code to my welcome.vue (oauth2 callback page)
<script>
export default {
mounted () {
const user = this.$auth.user
user['scope'] = 'some_role_from_db'
this.$auth.setUser(user)
}
}
</script>
but this code is never called, because application is immediately redirected to the page that user has selected before visiting login page (welcome.vue html markup is shown for 1 sec).
What is the correct way to set some attributes to this.$auth.user immediately after login? Is there some easy way to set role to user after OAUTH2 authentication?
user roles must came from server and it wrong to define it from client side ,
but if that is importent you can do it like that :
this.$auth.loginWith('google').then(() => {
const user = this.$auth.user
user['scope'] = 'some_role_from_db'
this.$auth.setUser(user)
})
I've added this section to my auth object in nuxt.config.js
rewriteRedirects: false
and so my app always redirects me to home url, and on home page I can access auth object like
<script>
export default {
mounted () {
const user = this.$auth.user
user['scope'] = 'some_role_from_db'
this.$auth.setUser(user)
}
}
</script>
I want to send a POST request to an external API with axios in a nuxt projekt where I use the nuxt auth module.
When a user is authenticated axios seems to automatically add an authorization header (which is fine and often required for calls to my backend API). However, when doing calls to an external API the header might not be accepted and cause the call to fail.
Is there any way to specify for which URLs the auth header should be added or excluded?
Here are the configurations of the auth and axios module in my nuxt.config
// Axios module configuration
axios: {
baseURL: '//localhost:5000',
},
// Auth module configuration
auth: {
strategies: {
local: {
endpoints: {
login: { url: '/auth/login', method: 'post', propertyName: 'token' },
logout: { url: '/auth/logout', method: 'delete' },
user: { url: '/auth/user', method: 'get', propertyName: 'user' },
},
},
},
}
Some more background:
In my particular usecase I want to upload a file to an Amazon S3 bucket, so I create a presigned upload request and then want to upload the file directly into the bucket. This works perfectly fine as long as the user is not authenticated.
const { data } = await this.$axios.get('/store/upload-request', {
params: { type: imageFile.type },
})
const { url, fields } = data
const formData = new FormData()
for (const [field, value] of Object.entries(fields)) {
formData.append(field, value)
}
formData.append('file', imageFile)
await this.$axios.post(url, formData)
I tried to unset the Auth header via the request config:
const config = {
transformRequest: (data, headers) => {
delete headers.common.Authorization
}
}
await this.$axios.post(url, formData, config)
This seems to prevent all formData related headers to be added. Also setting any header in the config via the headers property or in the transformRequest function does not work, which again causes the call to the external API to fail obviously (The request will be sent without any of these specific headers).
As I'm working with the nuxt axios module I'm not sure how to add an interceptor to the axios instance as described here or here.
Any help or hints on where to find help is very much appreciated :)
Try the following
Solution 1, create a new axios instance in your plugins folder:
export default function ({ $axios }, inject) {
// Create a custom axios instance
const api = $axios.create({
headers: {
// headers you need
}
})
// Inject to context as $api
inject('api', api)
}
Declare this plugin in nuxt.config.js, then you can send your request :
this.$api.$put(...)
Solution 2, declare axios as a plugin in plugins/axios.js and set the hearders according to the request url:
export default function({ $axios, redirect, app }) {
const apiS3BaseUrl = // Your s3 base url here
$axios.onRequest(config => {
if (config.url.includes(apiS3BaseUrl) {
setToken(false)
// Or delete $axios.defaults.headers.common['Authorization']
} else {
// Your current axios config here
}
});
}
Declare this plugin in nuxt.config.js
Personally I use the first solution, it doesn't matter if someday the s3 url changes.
Here is the doc
You can pass the below configuration to nuxt-auth. Beware, those plugins are not related to the root configuration, but related to the nuxt-auth package.
nuxt.config.js
auth: {
redirect: {
login: '/login',
home: '/',
logout: '/login',
callback: false,
},
strategies: {
...
},
plugins: ['~/plugins/config-file-for-nuxt-auth.js'],
},
Then, create a plugin file that will serve as configuration for #nuxt/auth (you need to have #nuxt/axios installed of course.
PS: in this file, exampleBaseUrlForAxios is used as an example to set the variable for the axios calls while using #nuxt/auth.
config-file-for-nuxt-auth.js
export default ({ $axios, $config: { exampleBaseUrlForAxios } }) => {
$axios.defaults.baseURL = exampleBaseUrlForAxios
// I guess that any usual axios configuration can be done here
}
This is the recommended way of doing things as explained in this article. Basically, you can pass runtime variables to your project when you're using this. Hence, here we are passing a EXAMPLE_BASE_URL_FOR_AXIOS variable (located in .env) and renaming it to a name that we wish to use in our project.
nuxt.config.js
export default {
publicRuntimeConfig: {
exampleBaseUrlForAxios: process.env.EXAMPLE_BASE_URL_FOR_AXIOS,
}
}
Description
I am trying to automatically route the user to the "Games.vue" component if they are already logged in. For authentication I am using Firebase and I check if they are logged in using:
var user = firebase.auth().currentUser;
if (user) {
// User is signed in.
} else {
// No user is signed in.
}
What I want to have happen is for the user to not see the Login page if they are already signed in. So they are taken directly to the Games page. I don't know how to accomplish this using Vue. I need something to run before the Login-component that redirects if logged in.
Attempt at solution
The only way I know how to solve this is to show the Login page, check if the Firebase user is logged in and then go to the Games page. This can work, but it isn't the behavior I am looking for. I am using the Vue router. Thank you for your help.
I would suggest to use a VueRouter global guard like so:
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
if (!user) {
next('login');
} else {
next();
}
})
That being said, you then need a way to specify which route requires authentication. I would suggest to use route meta fields like so:
routes = [
{
name: 'login',
path: '/login',
meta: {
requiresAuth: false
}
},
{
name: 'games',
path: '/games',
meta: {
requiresAuth: true
}
}
]
Now your guards becomes:
if (!user && to.meta.requiresAuth) {
next('login');
} else {
next();
}
Vue router provides an example for this use case, take a look at the documentation.
TIP: Make sure to subscribe to auth changes using Firebase onAuthStateChanged method.
let user = firebase.auth().currentUser;
firebase.auth().onAuthStateChanged(function(user) {
user = user;
});
EDIT: To redirect once logged in, just watch for auth changes and redirect using router.push.
auth.onAuthStateChanged(newUserState => {
user = newUserState;
if (user) {
router.push("/games");
}
});
I am new to expressJs and PassportJS trying to implement an API which return all basic details for a user i.e
{
isUserLogin: true or false,
allowedActions: [],
applicationUrl: [],
pageComponents: [],
settings: []
}
So the problem that I am facing is if I implement passport.js than guest users are getting unauthorized. Below is my code.
router.js
authRoutes.get('/init', passport.authenticate('bearer', { session: true }), authController.init);
controller.js
exports.init = (req, res) => {
//here is my login to get params. Guest user not able to reach it.
res.status(200).send(params);
};
I think it must be a simple setting at router level but unable to get proper document for this. I am stuck on this for more than 6 days. Any suggestions which could lead me in the right direction will be helpful.
Thanks in advance.
This is what passport-anonymous for.
Install with: npm install passport-anonymous
Then use the strategy
const AnonymousStrategy = require('passport-anonymous').Strategy;
passport.use(new AnonymousStrategy());
Then on your route, pass array of authentication strategies instead of string:
authRoutes.get('/init', passport.authenticate(['bearer', 'anonymous'], { session: true }), authController.init);
And on the controller, you can check whether the user is logged in by checking the req.user object. Keep in mind that you must put anonymous after the bearer in the array
exports.init = (req, res) => {
if (req.user) {
console.log("Logged in");
} else {
console.log("Guest");
}
res.status(200).send(params);
};
I have an authentication on my nuxt web-app, using the nuxt/auth module. I also use modular vuex stores to handle different states. After I login, everything is fine and I can navigate through the app normally. But when I try to reload the page or access it directly through a URL, the user is not accessible, thus, the whole web-app becomes unusable. I try to access the user object with this.context.rootState.auth.user, which is null after page-reload or direct access. Strangely enough, this only happens in production.
I already tried to add an if-guard, but sadly the getter is not reactive. Probably because it´s a nested object. This is my current getter:
get someGetter() {
if (!this.context.rootState.auth.user) {
return []
}
const userId = this.context.rootState.auth.user.id as string
const arr = []
for (const item of this.items) {
// Using userId to add something to arr
}
return arr
}
Is there a way to force nuxt to finish the authentication before initialising the vuex-modules, or to make this getter reactive, so it will trigger again, when the user object is accessible?
This is what my auth-config looks like in nuxt.config.ts:
auth: {
strategies: {
local: {
_scheme: '#/auth/local-scheme',
endpoints: {
login: {
url: '/api/authenticate',
method: 'post',
propertyName: false
},
logout: { url: '/api/logout', method: 'post' },
user: { url: '/api/users/profile', propertyName: false }
}
},
// This dummy setting is required so we can extend the default local scheme
dummy: {
_scheme: 'local'
}
},
redirect: {
logout: '/login'
}
}
EDIT
I resolved this by following Raihan Kabir´s answer. Using vuex-persistedstate in an auth-plugin, which is triggered every time the server renders the page. The plugin saves the userId in a cookie, so the store can use it as a fallback, if the auth-module isn´t ready.
The thing is, the vuex clears data on reload/refresh to keep credentials secure. That's what vuex is. If you want to store data for long time without being interrupted after reloading, you should use localstorage for that. But localstorage is not recommended for storing credentials.
If you need only user_id to keep in the vuex, use Cookie instead. And try something like this in your store's index.js file -
export const actions = {
// This one runs on the beginning of reload/refresh
nuxtServerInit ({ commit }, { req }) {
if (req.headers.cookie) {
const parsed = cookieparser.parse(req.headers.cookie)
try {
// get user id that you would set on auth as Cookie
user_id = parsed.uid
} catch (err) {
// error here...
}
}
// perform login and store info on vuex store
commit('authUserOnReload', user_id)
},
}
// Define Mutations
export const mutations = {
authUserOnReload (state, user_id) {
// perform login here and store user
}
}