无法使用Lua验证令牌。

huangapple go评论123阅读模式
英文:

Can't validate tokens with lua

问题

我有一个使用Golang编写的应用程序。它创建了一个访问令牌。我需要使用Lua检查令牌的有效性。这是我的Lua代码:

  1. local jwt = require "resty.jwt"
  2. function loadEnvFile(filepath)
  3. local env = {}
  4. local file, err = io.open(filepath, "r")
  5. if not file then
  6. return env, err
  7. end
  8. for line in file:lines() do
  9. if not line:match("^%s*#") and line:match("%S") then
  10. local key, value = line:match("^%s*([^=]+)=(.+)$")
  11. if key and value then
  12. env[string.gsub(key, "^%s*(.-)%s*$", "%1")] = string.gsub(value, "^%s*(.-)%s*$", "%1")
  13. end
  14. end
  15. end
  16. file:close()
  17. return env
  18. end
  19. local env = loadEnvFile("./.env")
  20. if next(env) == nil then
  21. ngx.log(ngx.ERR, "Файл .env не содержит данных или не удалось загрузить его")
  22. -- 处理文件加载错误
  23. return
  24. end
  25. -- 从请求中获取令牌(在这种情况下从Authorization头部)
  26. local access_token = ngx.var.http_authorization
  27. local secret_key = env["JWT_SECRET_KEY"]
  28. -- 检查令牌是否存在
  29. if not access_token then
  30. ngx.status = ngx.HTTP_UNAUTHORIZED
  31. ngx.say("Ошибка авторизации: Токен доступа отсутствует")
  32. ngx.exit(ngx.HTTP_UNAUTHORIZED)
  33. end
  34. -- 检查令牌
  35. local jwt_obj = jwt:verify(secret_key, access_token)
  36. -- 检查令牌验证结果
  37. if not jwt_obj.verified then
  38. ngx.status = ngx.HTTP_UNAUTHORIZED
  39. ngx.say("Ошибка авторизации: Неверный токен доступа")
  40. ngx.exit(ngx.HTTP_UNAUTHORIZED)
  41. end
  42. -- 设置响应头和状态码
  43. ngx.header.content_type = "text/plain"
  44. ngx.status = ngx.HTTP_OK
  45. -- 发送响应给客户端
  46. ngx.say("Токен доступа: ", access_token)
  47. ngx.say("Секретный ключ: ", secret_key)
  48. ngx.say("Результат проверки: ", jwt_obj.verified)
  49. ngx.flush(true)

这是我的server.conf配置文件:

  1. events {
  2. worker_connections 1024;
  3. }
  4. http {
  5. lua_package_path "lua-script/?.lua;/usr/local/share/lua/5.1/resty/?.lua;;";
  6. server {
  7. listen 80;
  8. location /api/pomo {
  9. access_by_lua_file <path_to_lua_file>;
  10. proxy_pass http://localhost:1323;
  11. }
  12. location / {
  13. proxy_pass http://localhost:1323;
  14. }
  15. }
  16. }

在我使用的localhost:80/api/pomo路由上,我总是收到无效令牌的错误。但是在localhost:1323上,相同的令牌可以正常工作。

我该如何使用Lua检查令牌的有效性?也就是说,最终的结构应该是这样的:请求 ↔︎ Nginx(Lua)↔︎ Golang。我通过OpenResty运行带有Lua代码的Nginx。

这是生成令牌的Golang代码:

  1. func GenerateToken(userID uint) string {
  2. claims := &JwtCustomClaims{
  3. userID,
  4. generateRandomString(32),
  5. jwt.RegisteredClaims{
  6. ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour * 72)),
  7. },
  8. }
  9. token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
  10. signedToken, _ := token.SignedString([]byte(os.Getenv("JWT_SECRET_KEY")))
  11. return signedToken
  12. }

我不明白问题出在哪里。

英文:

I have a golang application. It creates an access token. I need to check the validity of a token using lua. Here is my lua code:

  1. local jwt = require &quot;resty.jwt&quot;
  2. function loadEnvFile(filepath)
  3. local env = {}
  4. local file, err = io.open(filepath, &quot;r&quot;)
  5. if not file then
  6. return env, err
  7. end
  8. for line in file:lines() do
  9. if not line:match(&quot;^%s*#&quot;) and line:match(&quot;%S&quot;) then
  10. local key, value = line:match(&quot;^%s*([^=]+)=(.+)$&quot;)
  11. if key and value then
  12. env[string.gsub(key, &quot;^%s*(.-)%s*$&quot;, &quot;%1&quot;)] = string.gsub(value, &quot;^%s*(.-)%s*$&quot;, &quot;%1&quot;)
  13. end
  14. end
  15. end
  16. file:close()
  17. return env
  18. end
  19. local env = loadEnvFile(&quot;./.env&quot;)
  20. if next(env) == nil then
  21. ngx.log(ngx.ERR, &quot;Файл .env не содержит данных или не удалось загрузить его&quot;)
  22. -- Обработка ошибки загрузки файла
  23. return
  24. end
  25. -- Получение токена из запроса данном случае из заголовка Authorization)
  26. local access_token = ngx.var.http_authorization
  27. local secret_key = env[&quot;JWT_SECRET_KEY&quot;]
  28. -- Проверка наличия токена
  29. if not access_token then
  30. ngx.status = ngx.HTTP_UNAUTHORIZED
  31. ngx.say(&quot;Ошибка авторизации: Токен доступа отсутствует&quot;)
  32. ngx.exit(ngx.HTTP_UNAUTHORIZED)
  33. end
  34. -- Проверка токена
  35. local jwt_obj = jwt:verify(secret_key, access_token)
  36. -- Проверка результата проверки токена
  37. if not jwt_obj.verified then
  38. ngx.status = ngx.HTTP_UNAUTHORIZED
  39. ngx.say(&quot;Ошибка авторизации: Неверный токен доступа&quot;)
  40. ngx.exit(ngx.HTTP_UNAUTHORIZED)
  41. end
  42. -- Передача заголовков ответа и кода статуса
  43. ngx.header.content_type = &quot;text/plain&quot;
  44. ngx.status = ngx.HTTP_OK
  45. -- Отправка ответа клиенту
  46. ngx.say(&quot;Токен доступа: &quot;, access_token)
  47. ngx.say(&quot;Секретный ключ: &quot;, secret_key)
  48. ngx.say(&quot;Результат проверки: &quot;, jwt_obj.verified)
  49. ngx.flush(true)

Here is my server.conf:

  1. events {
  2. worker_connections 1024;
  3. }
  4. http {
  5. lua_package_path &quot;lua-script/?.lua;/usr/local/share/lua/5.1/resty/?.lua;;&quot;;
  6. server {
  7. listen 80;
  8. location /api/pomo {
  9. access_by_lua_file &lt;путь к lua файлу&gt;;
  10. proxy_pass http://localhost:1323;
  11. }
  12. location / {
  13. proxy_pass http://localhost:1323;
  14. }
  15. }
  16. }

On the localhost:80/api/pomo route, which I use, I always get an invalid token error. But on localhost:1323 the same token works correctly.

How do I check the validity of a token using lua??? That is, in the end, the structure should be like this request ↔︎ nginx(lua) ↔︎ golang. I run nginx with lua code through openresty.

Here is the go token generation code:

  1. func GenerateToken(userID uint) string {
  2. claims := &amp;JwtCustomClaims{
  3. userID,
  4. generateRandomString(32),
  5. jwt.RegisteredClaims{
  6. ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour * 72)),
  7. },
  8. }
  9. token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
  10. signedToken, _ := token.SignedString([]byte(os.Getenv(&quot;JWT_SECRET_KEY&quot;)))
  11. return signedToken
  12. }

I don't understand what's wrong with me

答案1

得分: 1

我解决了这个问题。jwt_secret_key从.env文件中存储在lua中的""中。我只是添加了去除""的方法,然后它就起作用了。

以下是lua代码本身:

  1. local jwt = require "resty.jwt"
  2. local cjson = require "cjson"
  3. function loadEnvFile(filepath)
  4. local env = {}
  5. local file, err = io.open(filepath, "r")
  6. if not file then
  7. return env, err
  8. end
  9. for line in file:lines() do
  10. if not line:match("^%s*#") and line:match("%S") then
  11. local key, value = line:match("^%s*([^=]+)=(.+)$")
  12. if key and value then
  13. env[string.gsub(key, "^%s*(.-)%s*$", "%1")] = string.gsub(value, "^%s*(.-)%s*$", "%1")
  14. end
  15. end
  16. end
  17. file:close()
  18. return env
  19. end
  20. local env = loadEnvFile("./.env")
  21. if next(env) == nil then
  22. ngx.say(ngx.ERR, "Файл .env не содержит данных или не удалось загрузить его")
  23. return
  24. end
  25. -- Получение токена из запроса данном случае из заголовка Authorization)
  26. local authorization_header = ngx.var.http_authorization
  27. local access_token = nil
  28. if authorization_header and authorization_header:find("Bearer") then
  29. access_token = string.gsub(authorization_header, "Bearer ", "")
  30. end
  31. -- Проверка наличия токена
  32. if not access_token then
  33. ngx.header.content_type = "text/plain"
  34. ngx.status = ngx.HTTP_UNAUTHORIZED
  35. ngx.say("Ошибка авторизации: Токен доступа отсутствует")
  36. ngx.exit(ngx.HTTP_UNAUTHORIZED)
  37. end
  38. -- Проверка токена
  39. local secret_key = env["JWT_SECRET_KEY"]
  40. secret_key = string.sub(secret_key, 2, -2)
  41. local jwt_obj = jwt:verify(secret_key, access_token)
  42. -- Вывод содержимого объекта jwt_obj в логи Nginx
  43. ngx.say(ngx.DEBUG, "jwt_obj: ", cjson.encode(jwt_obj))
  44. ngx.say(secret_key)
  45. -- Проверка результата проверки токена
  46. if not jwt_obj.verified then
  47. ngx.header.content_type = "text/plain"
  48. ngx.status = ngx.HTTP_UNAUTHORIZED
  49. ngx.say("Ошибка авторизации: Неверный токен доступа")
  50. ngx.exit(ngx.HTTP_UNAUTHORIZED)
  51. end
  52. -- Извлечение времени выпуска (iat) и времени истечения (exp) из полезной нагрузки JWT
  53. local iat = jwt_obj.payload.iat
  54. local exp = jwt_obj.payload.exp
  55. -- Отправка ответа клиенту
  56. ngx.header.content_type = "text/plain"
  57. ngx.status = ngx.HTTP_OK
  58. ngx.say("Время выпуска (iat): ", iat)
  59. ngx.say("Время истечения (exp): ", exp)
  60. ngx.say("Токен доступа: ", access_token)
  61. ngx.say("Секретный ключ: ", secret_key)
  62. ngx.say("Результат проверки: ", jwt_obj.verified)
  63. ngx.flush(true)
英文:

i solved the problem.
jwt_secret_key from .env was stored in lua in "". I just added the remove "" method and it worked.

Here is the lua code itself:

  1. local jwt = require &quot;resty.jwt&quot;
  2. local cjson = require &quot;cjson&quot;
  3. function loadEnvFile(filepath)
  4. local env = {}
  5. local file, err = io.open(filepath, &quot;r&quot;)
  6. if not file then
  7. return env, err
  8. end
  9. for line in file:lines() do
  10. if not line:match(&quot;^%s*#&quot;) and line:match(&quot;%S&quot;) then
  11. local key, value = line:match(&quot;^%s*([^=]+)=(.+)$&quot;)
  12. if key and value then
  13. env[string.gsub(key, &quot;^%s*(.-)%s*$&quot;, &quot;%1&quot;)] = string.gsub(value, &quot;^%s*(.-)%s*$&quot;, &quot;%1&quot;)
  14. end
  15. end
  16. end
  17. file:close()
  18. return env
  19. end
  20. local env = loadEnvFile(&quot;./.env&quot;)
  21. if next(env) == nil then
  22. ngx.say(ngx.ERR, &quot;Файл .env не содержит данных или не удалось загрузить его&quot;)
  23. return
  24. end
  25. -- Получение токена из запроса данном случае из заголовка Authorization)
  26. local authorization_header = ngx.var.http_authorization
  27. local access_token = nil
  28. if authorization_header and authorization_header:find(&quot;Bearer&quot;) then
  29. access_token = string.gsub(authorization_header, &quot;Bearer &quot;, &quot;&quot;)
  30. end
  31. -- Проверка наличия токена
  32. if not access_token then
  33. ngx.header.content_type = &quot;text/plain&quot;
  34. ngx.status = ngx.HTTP_UNAUTHORIZED
  35. ngx.say(&quot;Ошибка авторизации: Токен доступа отсутствует&quot;)
  36. ngx.exit(ngx.HTTP_UNAUTHORIZED)
  37. end
  38. -- Проверка токена
  39. local secret_key = env[&quot;JWT_SECRET_KEY&quot;]
  40. secret_key = string.sub(secret_key, 2, -2)
  41. local jwt_obj = jwt:verify(secret_key, access_token)
  42. -- Вывод содержимого объекта jwt_obj в логи Nginx
  43. ngx.say(ngx.DEBUG, &quot;jwt_obj: &quot;, cjson.encode(jwt_obj))
  44. ngx.say(secret_key)
  45. -- Проверка результата проверки токена
  46. if not jwt_obj.verified then
  47. ngx.header.content_type = &quot;text/plain&quot;
  48. ngx.status = ngx.HTTP_UNAUTHORIZED
  49. ngx.say(&quot;Ошибка авторизации: Неверный токен доступа&quot;)
  50. ngx.exit(ngx.HTTP_UNAUTHORIZED)
  51. end
  52. -- Извлечение времени выпуска (iat) и времени истечения (exp) из полезной нагрузки JWT
  53. local iat = jwt_obj.payload.iat
  54. local exp = jwt_obj.payload.exp
  55. -- Отправка ответа клиенту
  56. ngx.header.content_type = &quot;text/plain&quot;
  57. ngx.status = ngx.HTTP_OK
  58. ngx.say(&quot;Время выпуска (iat): &quot;, iat)
  59. ngx.say(&quot;Время истечения (exp): &quot;, exp)
  60. ngx.say(&quot;Токен доступа: &quot;, access_token)
  61. ngx.say(&quot;Секретный ключ: &quot;, secret_key)
  62. ngx.say(&quot;Результат проверки: &quot;, jwt_obj.verified)
  63. ngx.flush(true)

huangapple
  • 本文由 发表于 2023年7月13日 06:15:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/76674789.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定