问题
I want to add user id field to token returned from /api/login
Currently it's:
{
"username": "user",
"roles": [
"ROLE_USER"
],
"token_type": "Bearer",
"access_token": "eyJhbGciOiJIUzI1NiJ9.2uk2YoHsyd7bqUdtUYN19ef..",
"expires_in": 3600,
"refresh_token": "eyJhbGciOiJIUzI1NiJ9.eyJwcmluY2lwYWwiOiJINH.."
}
I need:
{
"id": "1",
"username": "user",
"roles": [
"ROLE_USER"
],
"token_type": "Bearer",
"access_token": "eyJhbGciOiJIUzI1NiJ9.2uk2YoHsyd7bqUdtUYN19ef..",
"expires_in": 3600,
"refresh_token": "eyJhbGciOiJIUzI1NiJ9.eyJwcmluY2lwYWwiOiJINH.."
}
the target - queries with user id, like POST /api/something Is there any other approaches? Thanks in advance
回答1:
You have not mentioned the Grails version, so I am posting the answer which I have implemented for Grails 2.4.4
1st thing you need to implement the AccessTokenJsonRenderer
interface in your custom class created under src/groovy
like below.
import grails.plugin.springsecurity.SpringSecurityUtils
import grails.plugin.springsecurity.rest.token.AccessToken
import grails.plugin.springsecurity.rest.token.rendering.AccessTokenJsonRenderer
import groovy.json.JsonBuilder
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.security.core.GrantedAuthority
/**
* Created by Prakash Thete on 17/04/2018
*/
class CustomAppRestAuthTokenJsonRenderer implements AccessTokenJsonRenderer {
@Override
String generateJson(AccessToken accessToken){
// Add extra custom parameters if you want in this map to be rendered in login response
Map response = [
id : accessToken.principal.id,
username : accessToken.principal.username,
access_token : accessToken.accessToken,
token_type : "Bearer",
refresh_token: accessToken.refreshToken,
roles : accessToken.authorities.collect { GrantedAuthority role -> role.authority }
]
return new JsonBuilder( response ).toPrettyString()
}
}
2nd thing you need to create the bean of our custom class in resources.groovy
, like below
// For overriding the token json renderer
accessTokenJsonRenderer(CustomAppRestAuthTokenJsonRenderer)
Now after hitting the api/login
you will receive the id of the user along with the other details.
Hope this helps !
回答2:
If you want to add even more details about the user in your Auth JSON response, you can use the principal ID and query for the user as follows.
Notice the addition of the @Transactional annotation.
import grails.gorm.transactions.Transactional
import grails.plugin.springsecurity.rest.token.AccessToken
import grails.plugin.springsecurity.rest.token.rendering.AccessTokenJsonRenderer
import groovy.json.JsonBuilder
import org.springframework.security.core.GrantedAuthority
@Transactional
class CustomAuthTokenRenderer implements AccessTokenJsonRenderer {
@Override
String generateJson(AccessToken accessToken) {
// User the principal ID to get an instance of the user from the database
User user = User.get accessToken.principal.id as Long
// Add extra custom parameters if you want in this map to be rendered in login response
Map res = [
id : user.id,
username : user.username,
firstName : user.firstName,
lastName : user.lastName,
profilePicture : user.profilePicture,
dateOfBirth : user.dob,
expiration : accessToken.expiration,
access_token : accessToken.accessToken,
token_type : "Bearer",
refresh_token : accessToken.refreshToken,
roles : accessToken.authorities.collect { GrantedAuthority role -> role.authority },
friends: user.friends.collect { Friend friend ->
[
id : friend.id,
firstName : friend.firstName,
dateCreated : friend.dateCreated,
lastUpdated : friend.lastUpdated,
]
}
]
return new JsonBuilder(res).toPrettyString()
}
}
It doesn't matter what you want to add to the response, with the user object, you can add almost anything. Just don't be tempted to make too many queries as this will result in a very slow login process.
来源:https://stackoverflow.com/questions/49715689/grails-rest-security-add-user-id-to-token