如何在微服务架构中使Auth服务与其他服务脱钩?

时间:2019-08-03 15:14:15

标签: authentication flask microservices logout coupling

我有一套微服务,其中一个负责身份验证。所有服务都使用共享库,例如flask_jwt_extended,以及用于验证传入请求的共享密钥(例如,使用flask_jwt_extendedjwt_required装饰器)。

身份验证服务的主要端点是UserLogin和UserLogout,诸如此类:

class UserLogin(Resource):

    def __init__(self, *args, **kwargs):
        self.parser = reqparse.RequestParser()
        self.parser.add_argument('email', type=str, required=True)
        self.parser.add_argument('password', type=str, required=True)


    def post(self):
        args = self.parser.parse_args()
        email = args.get('email')
        password = args.get('password')

        user = User.query.filter_by(email=email).first()
        if not user:
            return jsonify({'message': 'User does not exist'})

        if user.verify_hash(password):
            access_token = create_access_token(identity=user.email) 
            return jsonify({'access_token': access_token})
        else:
            return jsonify({'message': 'Wrong credentials'})


class UserLogout(Resource):

    @jwt_required
    def post(self):
        #Get the token and presist 
        jti = get_raw_jwt()['jti']        
        blocked_token = BlockedTokens(jti=jti) 
        db.session.add(blocked_token)
        db.session.commit()
        return jsonify({'message': 'logged out'})

然后在其他服务中,我使用jwt_required装饰器保护端点,这些装饰器仅验证传入请求的令牌(没什么特别的):

class PostDetails(Resource):

    @jwt_required
    def get(self, post_id):
        pass

当然,所有服务都共享相同的密钥:

app = app = Flask(__name__,)
app.config.from_mapping(JWT_SECRET_KEY=os.environ['JWT_SECRET_KEY']) 

注销操作理想地应如下:

  1. 将访问令牌存储在身份验证服务的数据库中。
  2. 对于每个请求,如果其令牌在黑名单中,则将其阻止。

我的问题是:

  1. 如何在不引入服务之间进一步耦合的情况下检查其他服务(auth服务除外)中被阻止的令牌?

  2. 是否可以通过不共享任何库或密钥进一步分离服务?

编辑:我为问题添加了更多详细信息和代码段,希望可以更好地阐明和说明问题。

1 个答案:

答案 0 :(得分:1)

基于以上评论。

简短的回答是,是的,这可能会增加auth服务的开销,但这是分离服务并将身份验证逻辑限制在同一服务中的最佳方法。

另一种方法是将令牌放入分布式缓存中,并在令牌被列入黑名单时对其进行验证。您只能将令牌保留在令牌的有效期限内的缓存中。假设您的令牌到期时间为15分钟,那么您将仅检查最近15分钟内生成的缓存中的令牌,其余令牌无论如何都已过期,可以删除。这样可以使缓存的大小保持较小,并且可以更快地进行检查。可以在所有服务之间共享此缓存服务。

通常,我们具有验证令牌的网关服务(公共端点),并且该服务可以调用缓存服务以检查令牌是否在缓存黑名单中。