Recently i started to learn how to use Nuxtjs and while learning how to use its Auth module i came across a problem.
I'm able to log in and I want to check the scope of the accounts, i tried doing it using the "scopeKey" property of "Auth". From the back end i get the "scope" from the databse and it can either be "user" or "admin".
I have tried to set the scope with
scopeKey: 'scope'
But I get that scope is "undefined"/"null" when checking with
this.$auth.hasScope('admin') / this.$auth.hasScope('user')
or "this.$auth.hasScope(admin)" return an empty value when setting "scopeKey" to
scopeKey: 'data.scope'
or
scopeKey: 'user.scope'
Here is my auth strategy:
auth: {
strategies: {
local: {
scopeKey: 'scope',
endpoints: {
login: {
url: 'api/auth/login',
method: 'post',
propertyName: 'token',
},
logout: {
url: 'api/auth/logout',
method: 'get'
},
user: {
url: 'api/me',
method: 'get',
propertyName: data
}
}
}
},
redirect: {
login: '/auth/login',
logout: '/',
callback: '/auth/login',
home: '/dash/'
}
}
and here it is an example of the json that the auth module reads when i log in:
"data": {
"id": 2,
"name": "test1",
"email": "test#test.com",
"email_verified_at": null,
"scope": "admin",
"created_at": "2019-08-01 13:11:49",
"updated_at": "2019-08-01 13:11:49"
},
I can access the scope value on the front end page with
$auth.user.scope
or with
$auth.$state.user.scope
But how can I give the "scope" to the "scopeKey" property in the nuxt.config.js file while setting the "auth" properties/strategy?
edit:
I have tried moving it inside the auth object or deleting the property and I still get false on $auth.hasScope('admin') and $auth.hasScope('user') which means scopeKey is still undefined and i'm not sure why.
The scopeKey is 'scope' by default. You don't need to set it again.
For me it worked by doing server side change.
When I put string value in scope, it does not work
$data['scope'] = "admin";
But when I changed it to array, $auth.hasScope('admin') works;
$data['scope'] = array("admin", "test");
Hope it helps.
scopeKey: 'scope' should not be placed inside strategies object.
Put it directly in the auth object.
Take a look at default config.
P.S. You can even delete this property from your auth config object, because 'scope' is default value for scopeKey.
Somehow hasScope() is not working for me too, so I directly checked the user object, I also has token in my response.
I am having a type variable in my response that tells me if the user is admin or someone else.
add this into your middleware
export default function ({ $auth, redirect }) {
if (!$auth.loggedIn) {
return redirect('/')
}
if ($auth.user.type != 'Super Admin') { // Super Admin or whatever the user you want to check
return redirect('/')
}
}
Related
I am working on Reactjs and using nextjs framework, I am working on "Login Logout" module and i just want that if user already logged in ( email set in cookie) then he should redirect to "dashboard" page,How can i do this ? I tried with following code but not working for me, giving me error ",Here is my current code
cookies returned from getServerSideProps Reason: undefined cannot be serialized as JSON
export async function getServerSideProps(context: { req: { headers: { cookies: any; }; }; }) {
const cookies = context.req.headers.cookies;
if (cookies && cookies.email) {
// email is present in cookies, so redirect to /dashboard
return {
redirect: {
destination: "/dashboard",
statusCode: 302, // temporary redirect
},
props: {},
};
}
return {
props: {
cookies,
},
};
}
When returning props.cookies from getServerSideProps, you are potentially returning the cookies as undefined. Use '' as the default value if missing.
You can do this:
return {
props: {
cookies: cookies || '',
},
};
You need to parse the cookies and you can get the cookies on the request you don't need the header
const cookies = JSON.parse(context.req.cookies);
if(cookies.email !== undefined)...
Authenticated user can still access the /login page. If I follow a link to /login page, I am redirected to a different page, which works fine. But if I enter /login into URL manually, I am still being taken to /login page, even though I am already logged in. What I am trying to achieve is, when the user is logged in, they should be redirected to /retailer/account page before any components are shown on the page (if they enter /login page manually).
I was trying using beforeMount() function, beforeCreate() function, following the documentation for auth: 'guest' middleware, however it does not seem to have any effect and loggedIn always returns false before the page is fully rendered.
My setup:
nuxt.config.js :
export default {
mode: 'universal',
target: 'static',
auth: {
cookie: {
prefix: 'auth_'
},
// Options
redirect: {
login: '/login',
logout: '/login',
callback: false,
home: '/retailer/account'
},
strategies: {
local: {
endpoints: {
login: {
url: '/auth/login',
method: 'post',
propertyName: 'access_token',
credentials: true
},
logout: {
url: '/auth/logout',
method: 'post'
},
user: {
url: '/auth/me',
method: 'post',
propertyName: '',
credentials: false
}
},
token: {
required: true,
type: 'Bearer',
global: true
},
autoFetchUser: true
}
},
preserveState: true,
watchLoggedIn: true
},
router: {
middleware: [
'auth'
]
}
}
layouts/default.vue :
export default {
auth: false
}
pages/retailer/account.vue :
export default {
middleware: 'auth'
}
pages/login.vue :
export default {
middleware: 'authenticated',
auth: 'guest'
}
Tried all kinds of middleware examples I could find and made some simple redirection code, but, as mentioned before, app.$auth.loggedIn always returns false from server-side, so I never get redirected.
middleware/authenticated.js
export default function ({ app, redirect }) {
if (app.$auth.loggedIn) {
return redirect(app.localePath({ name: 'index' }))
}
}
Later, when Vue hydrates the app, loggedIn is, of course, true.
Any ideas what I am doing wrong? Any guidance would be a huge help!
Nuxt auth module has a middleware auth can redirect unauthenticated user to login page, and redirect authenticated to home.
I see than the auth middleware is configured correctly in you nuxt.config.js.
The problem is that auth middleware only works on server side for SSR. but you configured to generate static website.
You can remove line target: 'static', from nuxt.config.js.
Or fllow this issue to find some help for static site auth:
https://github.com/nuxt/nuxt.js/issues/3023
I am trying to create an online meeting and recover its URL like explained here in the docs, but when the request is run I get this error:
{
"statusCode": 400,
"code": "AuthenticationError",
"message": "Error authenticating with resource",
"requestId": "652ea3be-6a97-47e8-bfc6-3d7d1d51d425",
"date": "2020-09-01T12:53:41.000Z",
"body": "{
"code":"AuthenticationError",
"message":"Error authenticating with resource",
"innerError":{
"date":"2020-09-01T13:53:41",
"request-id":"652ea3be-6a97-47e8-bfc6-3d7d1d51d425"
}
}"
}
I tried also the get started projet for JS and it's working fine so I can't spot the problem.
here is what I used:
const msalConfig = {
auth: {
clientId: 'my_app_id',
redirectUri: 'http://localhost:8080'
},
cache: {
cacheLocation: "sessionStorage",
storeAuthStateInCookie: false,
forceRefresh: false
}
};
const loginRequest = { scopes: [
'openid',
'profile',
'user.read',
'calendars.read',
'User.Read.All',
'User.Export.All'
]
}
const options = new MicrosoftGraph.MSALAuthenticationProviderOptions([
'user.read',
'calendars.read',
'OnlineMeetings.ReadWrite'
]);
const onlineMeeting = {
startDateTime:"2020-09-01T16:00:34.2444915-07:00",
endDateTime:"2020-09-01T16:30:34.2464912-07:00",
subject:"test meeting"
};
const authProvider = new MicrosoftGraph.ImplicitMSALAuthenticationProvider(msalClient, options);
// Initialize the Graph client
const graphClient = MicrosoftGraph.Client.initWithMiddleware({authProvider});
// then I call this inside an async function
let events = await graphClient.api('/users/my_UserPrincipalName/onlineMeetings').post(onlineMeeting);
//let events = await graphClient.api('/me/onlineMeetings').post(onlineMeeting);
// I tried with both calls and none of them worked
and here are the permissions on azure active directory:
So any ideas on how to solve this ?
thanks
You didn't provide a correct access token.
Since Create onlineMeeting only supports Delegated (work or school account) permission type, you need to get the access token with Auth code flow or Implicit flow.
The started project for JS is using Implicit flow. So you can use Implicit flow to get the access token.
Here is the example in Postman:
The Auth URL above is https://login.microsoftonline.com/{your tenant}/oauth2/v2.0/authorize.
I figured out how to make it work in my code:
let's call my user, which I used all this time, user "A", all I did is that I simply created another user "B" in Azure Active Directory and then logging in with this new user "B" in the login screen instead of the admin user "A" that I used before..... and now it's working.
But this does not explain the issue, so if anyone can explain the difference or why it didn't work with the first account, that would be very helpful.
I'm passing the response from chrome identity api to the tab that will run my vue powered chrome extension. I need to store this information inside my vue instance tu use it inside a component. I've tried to assign the info to a variable using this.username but it will result in undefined in console. What's wrong with the code and what's the best way to accomplish this?
component code
<script>
import { EventBus } from '../../event-bus';
export default {
data () {
return {
socket: null,
isRegistered: false,
isConnected: false,
username: null,
message: '',
}
},
created() {
},
mounted() {
chrome.runtime.onMessage.addListener(
function(request, sender){
console.log(request);
this.username = request.name;
this.isRegistered = true;
});
EventBus.$emit('open-connection')
// the variable is undefined and also the open-connection event are not emitted?
console.log(this.username)
EventBus.$on('connected', (socket) => {
console.log(socket)
this.socket = socket;
this.isConnected = true;
console.log(this.socket.id)
})
},
methods: {
// I was using this method but the function isn't called inside mounted, result in an error :(
connect(){
//if( this.isRegistered === false){
//this.username = this.username;
//this.isRegistered = true;
//EventBus.$emit('open-connection')
//return this.username;
// }
}
// methods here
}
}
</script>
<style scoped>
</style>
The response from identity api (I will omit the fields value for privacy):
{
"id": "100xxxxxx",
"name": "xxx",
"given_name": "xxxx",
"family_name": "xxxx",
"picture": "https://lh4.googleusercontent.com/xxxxx.jpg",
"locale": "xx"
}
NB: the response object is not accessible in this way key.val
EDIT
After some debug I've finally found a solution. The response information retrived by the api isn't really an object but a JSON. I've used the JSON.parse() function to make it an object and now I'm able to access to the fields using key.value syntax.
Perhaps you could use the chrome.storage to set/get the data rather than rely on the components state.
Otherwise can you share what the console.log(request) is giving you and what the background script looks like?
The question is how to get username, which I used to login, back from response object?
I'm creating the Auth0Lock instance by following code:
this._lock = new Auth0Lock(AUTH_CONFIG.clientId, AUTH_CONFIG.domain, AUTH_CONFIG.options);
and then I subscribe on "authenticated" event:
this._lock.on('authenticated', authResult => {
this._lock.getUserInfo(authResult.accessToken, function(error, profile) {
console.log('profile', profile); // --> undefined
if (error) {
// Handle error
}
});
})
I'm logging in by following credentials:
username: john#gmail.com password: 123456
I want to be able to see 'username: john#gmail.com' somewhere in authResult object.
But unfortunately I don't see.
Should I add something in Auth0lock options?
P.S. I've added following code inside the handler of "authenticated" event, but it returns undefined for profile.
I've just added scope: 'openid' into "auth" property of options
options: {
...
auth: {
...
scope: 'openid' <---
}
}