Create a role
In addition to the default role we provide, we also allow developers to create their custom role. There is a document about how to create a new role
Denylist
Default denylist with redis
Redis is a good option for denylist
that will allow fast in memory access to the list. In jwt_denylist
record, we implement denylist with redis. By setting redis
expiration time to be the same as jwt token
expiration time, this token can be automatically deleted from redis when the token expires.
def self.jwt_revoked?(payload, user)
# Check if in the denylist
$redis.get("user_denylist:#{user.id}:#{payload['jti']}").present?
end
def self.revoke_jwt(payload, user)
# REVOKE JWT
expiration = payload['exp'] - payload['iat']
$redis.setex("user_denylist:#{user.id}:#{payload['jti']}", expiration, payload['jti'])
end
Custom denylist
You can also implement denylist by your own strategies. You just need to rewrite two methods: jwt_revoked?
and revoke_jwt
in jwt_denylist.rb
, both of them accepting as parameters the JWT payload and the user
record, in this order.
def self.jwt_revoked?(payload, user)
# Does something to check whether the JWT token is revoked for given user
end
def self.revoke_jwt(payload, user)
# Does something to revoke the JWT token for given user
end
Dispatch requests
You can config dispatch_requests
in devise.rb
. When config it, you need to tell which requests will dispatch tokens for the user that has been previously authenticated (usually through some other warden strategy, such as one requiring username and email parameters). To configure it, you can add the the request path to dispath_requests.
jwt.dispatch_requests = [['POST', %r{^users/sign_in$}]]
Revocation requests
You can config dispatch_requests
in devise.rb
. When config it, you need to tell which requests will revoke incoming JWT tokens, and you can add the the request path to revocation_requests
jwt.revocation_requests = [['DELETE', %r{^users/sign_out$}]]
Jwt payload
user
records may also implement a jwt_payload method, which gives it a chance to add something to the JWT payload.
def jwt_payloads
# { 'foo' => 'bar' }
end
Jwt dispatch
You can add a hook method on_jwt_dispatch
on the user
record. It will execute when a token dispatched for that user instance, and it takes token and payload as parameters. And this method will call when you access the routes which in dispatch_requests
def on_jwt_dispatch(token, payload)
# do_something(token, payload)
end