Master-Agent模式的Rails应用借助JWT Token验证

一对Master-Agent模式Rails应用,Agent需要验证Master。通常考虑采用HTTP基础认证或者HTTP摘要认证。这里Agent不需要多用户支持,所以只要一个加密口令即可,无需用户名。本文介绍采用JWT实现基于Token验证,结合Rails 4.1的新特性,装载secrets.yml文件里的密钥,作为JWT Token的计算密钥,应用于Rails应用。

Agent端配置安装jwt Gem

Gemfile添加如下行

gem 'jwt'

然后执行bundle install

让所有Controller验证JWT Token

编辑app/controllers/application_controller.rb文件,

require 'jwt'class ApplicationController < ActionController::Base    ...before_action :validate_token# Validate JWT tokendef validate_token    begin    authz_header = request.headers['Authorization']    if authz_header.nil?        raise SecurityError.new("Authorization Header is missing")    end    token = authz_header.split(' ').last    JWT.decode(token, Rails.application.secrets.jwt_secret_key)    rescue JWT::DecodeError, SecurityError    render nothing: true, status: :unauthorized    endend    ...end

其中密钥Rails.application.secrets.jwt_secret_key需要配置config/secrets.yml

配置config/secrets.yml

development:    secret_key_base: c5e867eee171336e0b00d648a3d73cd176379ad9bc556ccc34102a046893c451add2b2fccb6d3ea914834cd9737e6ca432ecdf6cef8c81b61b79c8cad412ac88    jwt_secret_key: c5e867eee171336e0b00d648a3d73cd176379ad9bc556ccc34102a046893c451add2b2fccb6d3ea914834cd9737e6ca432ecdf6cef8c81b61b79c8cad412ac88test:    secret_key_base: eaddadc7e11e7228c78670537d53a5b62d5b3908a84dcad6340c4a8104052b9043271bb03ae1ce11b03efe72ce4547aec61a9b71891451568a1084c80ba388d2    jwt_secret_key: c5e867eee171336e0b00d648a3d73cd176379ad9bc556ccc34102a046893c451add2b2fccb6d3ea914834cd9737e6ca432ecdf6cef8c81b61b79c8cad412ac88# Do not keep production secrets in the repository,# instead read values from the environment.production:    secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>    jwt_secret_key: <%= ENV["JWT_SECRET_KEY"] %>

开发和测试环境取静态值,部署环境取环境变量的值。

配置.env文件存放环境变量

安装 dotenv gem,修改Gemfile,添加如下行

gem 'dotenv-rails'

请将’dotenv-rails’放在其他依赖环境变量的gem的前面,保存后执行bundle install

Rails.Root目录新建.env文件

JWT_SECRET_KEY: 4efe25e7fb153c392baf0787ee78c153a4fba5e6d7c8715b4a03849cd8a13b064ad2a636845e6753481613111dffb3c48c9a5a84fc38d50b757b3a2f46b8a493SECRET_KEY_BASE: 2d78298e02650fefd0381ae0be261064466ac028567a8c5d113b46f0e4696d3153b8bac9ab62828b2befc08c48b009678d4b5de0f47b72f7e5fce51800ce5fee

然后将.env添加到.gitignore里去,防止其被提交到版本库

与Capistrano集成

修改config/deploy.rb文件,添加如下Task

namespace :deploy do    desc 'Generate Secret key to .env file'task :generate_sceret_key do    on roles(:app), in: :parallel do    within release_path do        if test("! grep -q JWT_SECRET_KEY #{release_path.join('.env')}")            execute :rake, 'env:generate_secret[JWT_SECRET_KEY]'        end        if test("! grep -q SECRET_KEY_BASE #{release_path.join('.env')}")            execute :rake, 'env:generate_secret[SECRET_KEY_BASE]'        end             end    end    end    after :updated, :generate_sceret_keyend

Master端配置

采用RestClient与Agent端进行通信,需要在请求的头部加入JWT Token以通过Agent端验证。

#sync with agentdef sync    res = site['sync.json'].get    json =  JSON::parse(res.body)    puts jsonend#generate jwt tokendef generate_token    unless self.secret_key.nil?        self.token = JWT.encode("something_to_secret", self.secret_key)    endendprivate    def site        @_site ||= RestClient::Resource.new(self.endpoint, :headers => {"Authorization" => "Bearer #{self.token}"})    end

参考阅读

    JWT based authentication with Ember.js and RailsLoads environment variables from ‘.env’Generate a New Secret Token for Rails AppsA better way to manage the Rails secret tokenRails 4.1 generates a new secrets.yml file in the config folder
Master-Agent模式的Rails应用借助JWT Token验证

相关文章:

你感兴趣的文章:

标签云: