불로장생약 플러그와 JWT

13568 단어 elixirjwtjoseplug
저는 자바 세계(예를 들어 마이크로 파일 규범)에서 왔습니다. 그곳의 JWT 실현을 알고 있습니다. 저는 자바가 Elixir와 함께 운행하는 것을 보고 Elixir가 우리에게 가져다 준 모든 재즈를 얻고 싶습니다.중요한 것은 Phoenix 프레임을 사용하지 않는다는 것입니다.
Github 에서 이 프로젝트의 Elixir 소스 코드를 찾을 수 있습니다.
JWT에 관해서는 세부 사항이 많지 않다. 그것이 무엇인지, 어떻게 일을 하는지 (당신은 여기서 더 많은 정보를 얻을 수 있다: jwt.io)). 나는 단지 우리의 삶을 더욱 가볍게 할 수 있는 관점을 쓰고 싶다.

JWT 소개
JWT 또는 JSON 웹 토큰은 클라이언트에 대한 권한 부여를 위한 토큰 문자열입니다.클라이언트가 서버에 성공적으로 로그인되면 응답에서 JWT를 수신하여 브라우저 스토리지에 저장합니다.모든 후속 요청은 머리에 이 영패를 포함하고 서버에서 이 영패를 사용하여 이 요청을 권한을 부여하거나 부여하지 않습니다.고객은 심지어 디코딩을 필요로 하지 않는다.

세 줄을 찾다
우리가 JWT를 찾는 과정에서 우리는 실제적으로 세 개의 문자열을 찾고 있다. 그들은 함께 한 점으로 분리되어 하나의 JWT를 구성한다.이 세 문자열은 그 성질에 따라 명명되기 때문에 JWT를 다음과 같이 정의할 수 있습니다.
"Header"."Payload"."Signature"
헤드와 로드는 Base64Url 인코딩된 JSON에 불과합니다.이게 다야!누군가가 영패를 납치하려고 한다면, 그들은 헤더와 유효 부하를 쉽게 해독할 수 있다는 뜻이다.이것은 당신이 영원히 JWT에 민감한 정보를 저장해서는 안 된다는 것을 의미한다.예를 들어 우리는 online encoder 을 사용하여 JSON을 인코딩하거나 디코딩할 수 있다. 우리가 영패를 납치할 수만 있다면.

제이슨 보여줘.
이 JSON들이 어떤 모습인지 한번 봅시다.제목에는 서명에 사용되는 알고리즘에 대한 정보가 포함됩니다. 예를 들어 다음과 같습니다.
{"alg":"HS256","typ":"JWT"}
Base64Url 은
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
유효 하중에는 이른바 클레임이 포함되어 있다.세부 사항을 깊이 토론하지 않는 상황에서, 우리는 성명에 사용자에 대한 정보를 포함한다고 말할 수 있다. 예를 들어, 그의 이름, ID, 영패의 만료 시간, 자바 파일의 경우, 우리는 보통 그룹 목록을 저장한다. (그리고 권한을 부여하는 데 사용한다.)유효한 하중의 예는 다음과 같습니다.
{
"sub": "John Doe",
"user": "[email protected]",
"iss": "Server ms",
"exp": 1516239022,
"groups": ["guest"]
}
그 기본 대표는 다음과 같다.
eyJzdWIiOiJKb2huIERvZSIsInVzZXIiOiJqb2huZG9lQGhleS5jb20iLCJpc3MiOiJTZXJ2ZXIgbXMiLCJleHAiOjE1MTYyMzkwMjIsImdyb3VwcyI6WyJndWVzdCJdfQ

당신을 믿어도 될까요?
기호화폐의 마지막 부족한 부분은 서명이다.JWT에 서명한다는 것은 무슨 뜻입니까?영패 안의 서명은 무엇입니까?
검증 서명은 영패 검증의 일부로 여겨진다(검증의 다른 부분은 검사 만료 시간 등).만약 JWT가 유효하다면 이것은 JWT의 유효 부하를 신뢰할 수 있다는 것을 의미한다. 다시 말하면 유효 부하를 변경하는 사람이 없다. 즉, 영패와 서버의 전송 과정에서 신뢰할 수 있다는 것이다.
악의적으로 부하를 변경한 예는 공격자가 '그룹' 성명을 그룹 '관리자 포함' 등으로 변경함으로써 서버가 관리자가 허용하는 요청만 허용하도록 하는 것이다.
여기서 중요한 것은 서명과 암호화를 구분하는 것이다.우리가 이미 알고 있는 바와 같이, 헤더와 부하는base64url 인코딩에 불과하다.
The signature does not provide secrecy! 
기본적으로 JWT는 암호화되지 않습니다.JSON Web Encryption(JWE)은 암호화를 포함하므로 포함하지 않을 예정입니다.JSON 웹 서명 (JWS) 은 서명을 포함하고 있으며, Elixir에서 사용하는 방법을 보여 드리겠습니다.
JWS에 따라 여러 가지 유형의 서명 알고리즘을 사용할 수 있습니다.우리의 예시에서 우리는 HMAC을 사용하고 SHA-256 또는 더 짧은 HS256을 사용할 것이다.HMAC 알고리즘은 암호화 해시 함수(예를 들어 SHA-256)를 사용하여 유효한 하중과 비밀을 결합시키거나 간단한 단어와 결합시키려면 영패에 서명할 비밀이 필요하다.

이것은 내가 영원히 너에게 알려주지 않을 비밀이다
불로장생의 비밀은 어디에 숨겨져 있습니까?내 연구에서 사람들은 여러 방식으로 비밀을 저장하지만 기본 원칙은 변하지 않는다.
  • 비밀은 환경에 달려 있다.
  • 소스 코드 관리에 기밀을 저장해서는 안 된다.
  • 기밀 액세스를 관리해야 합니다.
  • 개인적으로 말하자면, 내가 사용하는 방법은 모든 비밀 파일이다. 그 중에서 비밀 파일은 파일 시스템에 저장되어 있으며, 'config.exs' 에서 불러온다.불리한 점은 기밀이 구축 (컴파일) 될 때 불러온다는 것을 의미하지만, 파일 시스템에 대한 접근 관리를 잘 할 수 있고, 원본 코드 관리에 기밀을 잘못 저장하는 것을 피할 수 있다는 것이다.https://github.com/thechangelog/changelog.com도 이런 방법을 사용한다
    또한 각 환경에서 일반적인 버전(예: MIX ENV=prod MIX release)을 사용하지 않도록 "releases.exs"를 사용할 수도 있습니다.이렇게 하면 시스템이 시작될 때 설정을 읽을 수 있습니다.
    우리도 환경 변수를 사용할 수 있다. 예를 들어 12요소 응용 프로그램이 제안한 https://12factor.net/config. 그러나 접근 관리는 더욱 까다로울 수 있다.다시 한 번, 당신에게 가장 적합한 것을 선택하세요.

    코드 보여주세요.
    자, 코드(Github) 때가 됐어요.중요한 부분을 강조합시다.
    보시다시피 저희는 다음과 같은 의존항만 사용합니다.
    {:plug_cowboy, "~> 2.0"},
    {:jason, "~> 1.2"},
    {:jose, "~> 1.10.1"}
    
    그래서 JWT 조작에 대해 저는 JOSE 라이브러리를 선택했습니다. 제 취향에 따라 완벽한 정보 압축 체험을 제공했습니다. 너무 높은 등급의 코드도 아니고 너무 낮은 등급의 코드도 아닙니다.

    프로그램당 플러그 파이프 1개
    Plug.Router를 사용하면 각 응용 프로그램에서 하나의 파이프만 정의할 수 있습니다.여기에는 융통성 있는 방법이 소개되어 있습니다.
    https://groups.google.com/g/elixir-lang-talk/c/U_o81N1VPfg
    그러나 나는 상술한 해결 방안을 채택하지 않았다.
    이외에도 "Plug.Router"를 사용하는 모듈마다 최소 두 개의 플러그(일치, 스케줄링)를 정의해야 하는 또 다른 문제가 있습니다.
    이 두 가지 중요한 정보를 결합하면 나의 코드는 아래와 같다.내 주 애플리케이션 라우터에서 내 파이프라인 및 전송을 정의했습니다.
    forward("/greetings", to: Greetings)
    forward("/login", to: Login)
    
    plug(Plug.Logger, log: :debug)
    plug(:match)
    plug(JwtExample.Plug.Auth, public_path: "/login")
    plug(Plug.Parsers,
      parsers: [:json],
      pass: ["application/json"],
      json_decoder: Jason)
    plug(:dispatch)
    
    보시다시피 사용자 정의 플러그인 JWT 예제를 사용합니다.플러그"public path"옵션을 사용하여 토큰의 인증을 확인하고 검증할 수 있습니다.이것은 예외를 설정합니다. 이 플러그인은 JWT 검사를 건너갑니다. 즉, 로그인 페이지에 JWT 검사가 있어서는 안 됩니다.추가 리소스의 경우 plug은 머리에서 JWT 토큰을 가져와 검증합니다.
    JOSE 라이브러리를 사용하여 JWT를 만들고 검증하는 것은 매우 간단합니다.
  • JWK - JSON 웹 키, 서명할 응용 프로그램 키가 들어 있습니다.
  • 정의된 알고리즘이 포함된 JWS-JSON 웹 서명
  • 우리가 신청한 JWT 클레임.
  • 생성된 코드는 다음과 같습니다.
    # JSON Web Keys
    jwk = %{
      "kty" => "oct",
      "k" => encode_secret()
    }
    
    # JSON Web Signature (JWS)*
    jws = %{
      "alg" => "HS256"
    }
    
    # JSON Web Token (JWT)*
    jwt = %{
      "iss" => Application.get_env(:jwt_example, :jwt_issuer),
      "sub" => id,
      "exp" => DateTime.utc_now() |> DateTime.add(expired_in * 60, :second) |> DateTime.to_unix(),
      "groups" => groups,
      "email" => email
    }
    
    {_, token} = JOSE.JWT.sign(jwk, jws, jwt) |> JOSE.JWS.compact()
    
    JWT 유효성 검사 코드는 다음과 같습니다.
    jwk = %{
      "kty" => "oct",
      "k" => encode_secret()
    }
    
    case JOSE.JWT.verify(jwk, token) do
      {true, claims, *_*} -> {:ok, claims}
      _ -> {:error, "Token signature verification failed!"}
    end
    
    그 중 영패는 청구 헤드에서 얻었기 때문에 우리는 성명을 했다.
    플러그인이 어떻게 기호화폐를 캡처하는지에 대한 자세한 정보는 원본 코드(Github에서 찾을 수 있습니다.코딩을 즐기세요!

    좋은 웹페이지 즐겨찾기