Openresty之jwt的token验证

        如果是第一次看这个文章,可以先看下这篇openresty介绍性的文章:Openresty概述介绍

        在使用代理的时候可能需要验证来访问请求的token,验证token代码也是在lua脚本文件中操作,然后通过access_by_lua_file过程进行拦截,然后获取里面的token,进行验证,验证通过与否做一些定制化的操作。

        使用openresty实现jwt的token验证需要如下几步:

  • 编写lua脚本文件,实现token获取和验证
  • 添加依赖库源文件到lualib目录
  • 拷贝lua代码文件到路径
  • 修改nginx.conf文件,token获取验证代码

1、编写lua脚本文件

脚本文件实现请求头header的token获取,然后使用函数验证token,我们命令为lua文件为access.lua,源代码如下:

local jwt = require "resty.jwt"
local cjson = require "cjson"

local secret = "token secret key"

local retdata = {
    code=ngx.HTTP_UNAUTHORIZED,
    message="token验证失败",
    data={}
}

local auth_header = ngx.req.get_headers()["Auth"]
--ngx.log(ngx.INFO, "auth_header = ",auth_header)
if auth_header == nil then
    ngx.log(ngx.ERR, "No Auth header")
    ngx.status = ngx.HTTP_UNAUTHORIZED
    ngx.header["Content-type"] = 'application/json'
    local output = cjson.encode(retdata)
    ngx.say(output)
    return ngx.exit(0)
end

local jwt_obj = jwt:verify(secret, auth_header)
if jwt_obj.verified == false then
    ngx.log(ngx.ERR, "Invalid token: ".. jwt_obj.reason)
    ngx.status = ngx.HTTP_UNAUTHORIZED
    ngx.header.content_type = "application/json; charset=utf-8"
    ngx.header["Content-type"] = 'application/json'
    local output = cjson.encode(retdata)
    ngx.say(output)
    return ngx.exit(0)
end

上面的代码可以看出我们引用了jwt模块,然后在代码里面首先定义了一个secret变量,这个变量是使用jwt生成token的秘钥,生成token和验证token的秘钥必须要一样,否则token验不过;然后代码里面从请求header里面获取键值为Auth的token值,你可以随意修改这个键值,只要前后保持一致就行,获取失败则直接返回认证失败,如果获取成功则进行下一步验证token有效性,验证失败则也返回token认证失败信息。

2、添加依赖库源文件到lualib目录

最后执行的时候可能会报没有jwt依赖库,需要拷贝一些依赖文件到/usr/local/openresty/lualib/resty目录下面,拷贝如下文件,文件有四个,文件名为

evp.lua
hmac.lua
jwt-validators.lua
jwt.lua

由于代码比较多,我打包成一个压缩文件,可以去这下:resty.jwt依赖库下载地址

3、拷贝lua代码文件

拷贝编写好的access.lua文件到路径/usr/local/openresty/nginx/lua/,如果路径没有,新建下这个路径

4、修改nginx.conf文件

在nginx.conf文件里面修改文件内容如下,实现token的获取和验证

#user  nobody;
worker_processes  1;
 
error_log  logs/error.log  error;
error_log  logs/error.log  notice;
error_log  logs/error.log  info;
pid        logs/nginx.pid;
 
events {
    worker_connections  1024;
}
 
 
http {
    include       mime.types;
    default_type  application/octet-stream;
 
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                     '$status $body_bytes_sent "$http_referer" '
                     '"$http_user_agent" "$http_x_forwarded_for"';
    # access_log  logs/access.log  main;
    # error_log   logs/error.log error; 
 
    lua_package_path "/usr/local/openresty/lualib/?.lua;/usr/local/openresty/nginx/lua/?.lua;";
    lua_package_cpath "/usr/local/openresty/lualib/?.so;;";
 
 
    sendfile        on;
    #tcp_nopush     on;
 
    #keepalive_timeout  0;
    keepalive_timeout  65;
    proxy_connect_timeout 3s;
 
    #gzip  on;
 
   
    # HTTPS server
    server {
       listen       80;
       server_name  localhost;
 
       location / {
            access_by_lua_file 	lua/access.lua;
            #设置代理目的url变量
            proxy_pass https://127.0.0.1;
       }
 
    }
 
}

lua_package_path "/usr/local/openresty/lualib/?.lua;/usr/local/openresty/nginx/lua/?.lua;";

access_by_lua_file     lua/access.lua;

第一句是添加lua代码的路径,第二句代码是指定所有请求都会经过access.lua文件,在里面实现前面代码实现的内容,主要就是获取header里面的token,然后对token进行验证,实现使用lua代码完成jwt的token验证功能。

猜你喜欢

转载自blog.csdn.net/u013896064/article/details/128712965