Grails REST security - Add user id to token

允我心安 提交于 2019-12-11 04:55:20

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!