firesphere/graphql-jwt

GraphQL JWT 认证

安装次数: 6,323

依赖项: 0

建议者: 0

安全: 0

星标: 18

关注者: 7

分支: 23

开放问题: 13

类型:silverstripe-vendormodule

2.0.0-RC1 2019-08-02 00:14 UTC

README

CircleCI Scrutinizer Code Quality codecov

许可证

GPL v3 或更高版本

GraphQL JSON Web Token 验证器

此模块提供用于创建 JSON Web Tokens 进行认证的 JWT 接口。

安装

composer require firesphere/graphql-jwt

默认配置存储在 _config\config.yml

为了通过 JWT 安全处理和存储数据,您需要在您的 .env 文件中设置一个密钥。

JWT_SIGNER_KEY="[your secret key]"

JWT_SIGNER_KEY 生成安全随机值的一个快速方法是使用 PHP CLI 命令。

php -r 'echo substr(base64_encode(random_bytes(64)), 0, 64) . "\n";'

您也可以使用公钥/私钥文件。

JWT_SIGNER_KEY="./path/to/private.key"
JWT_PUBLIC_KEY="./path/to/public.key"

注意:相对路径将与您的 BASE_PATH 相对(以 ./ 开头)。

目前,仅支持 RSA 密钥。不支持 ECDSA。测试文件夹中的密钥是由在线 RSA 密钥生成器生成的。

用于 HMAC 的签名密钥可以是任何长度(超过 B 字节的密钥将首先使用 H 进行哈希)。然而,小于 L 字节是强烈不建议的,因为它会降低函数的安全性强度。因此,对于 SHA-256,签名密钥的长度应在 16 到 64 字节之间。

tests/keys 中的密钥不应被信任!

配置

由于 admin/graphql 是专门为 CMS graphql 访问保留的,因此您需要为您的前端应用程序注册一个自定义模式,并将提供的查询和突变应用于该模式。

例如,假设您已决定在 /api URL 下创建一个名为 frontend 的模式

---
Name: my-graphql-schema
---
SilverStripe\GraphQL\Manager:
  schemas:
    frontend:
      types:
        MemberToken: 'Firesphere\GraphQLJWT\Types\MemberTokenTypeCreator'
        Member: 'Firesphere\GraphQLJWT\Types\MemberTypeCreator'
      mutations:
        createToken: 'Firesphere\GraphQLJWT\Mutations\CreateTokenMutationCreator'
        refreshToken: 'Firesphere\GraphQLJWT\Mutations\RefreshTokenMutationCreator'
      queries:
        validateToken: 'Firesphere\GraphQLJWT\Queries\ValidateTokenQueryCreator'
---
Name: my-graphql-injections
---
SilverStripe\Core\Injector\Injector:
  SilverStripe\GraphQL\Manager.frontend:
    class: SilverStripe\GraphQL\Manager
    constructor:
      identifier: frontend
  SilverStripe\GraphQL\Controller.frontend:
    class: SilverStripe\GraphQL\Controller
    constructor:
      manager: '%$SilverStripe\GraphQL\Manager.frontend'
---
Name: my-graphql-routes
---
SilverStripe\Control\Director:
  rules:
    api:
      Controller: '%$SilverStripe\GraphQL\Controller.frontend'
      Stage: Live

登录

要生成 JWT 令牌,请向 createToken 突变发送登录请求

mutation {
  createToken(Email: "admin", Password: "password") {
    Token, // ...request or you won't have a token
    ID,
    FirstName,
    Surname
  }
}

验证令牌

如果您有一个应用程序并想验证您的令牌,您可以通过 validateToken 方法来实现

query validateToken {
  validateToken {
    Valid
    Message
    Code
  }
}

它只需要调用端点。令牌应通过您的中间件作为请求头中的 Authorization: Bearer [token]。如果令牌有效,您将收到如下响应

{
  "data": {
    "validateToken": {
      "Valid": true,
      "Message": "",
      "Code": 200,
      "__typename": "ValidateToken"
    }
  }
}

如果令牌无效,则 Valid 将为 false

匿名令牌

虽然不建议,但可以使用匿名令牌。当使用匿名验证器时,SilverStripe 将在 Members 表中生成一个默认的数据库记录,电子邮件为 anonymous,默认没有权限。

要启用匿名令牌,请将以下内容添加到您的配置 .yml

SilverStripe\Core\Injector\Injector:
  Firesphere\GraphQLJWT\Mutations\CreateTokenMutationCreator:
    properties:
      CustomAuthenticators:
        - Firesphere\GraphQLJWT\Authentication\AnonymousUserAuthenticator

然后您可以使用以下查询创建匿名登录。

mutation {
  createToken(Email: "anonymous") {
    Token
  }
}

注意:如果默认匿名验证器不符合您的需求,您可以将任何其他核心 SilverStripe 验证器注入到 CustomAuthenticators

警告:默认的 AnonymousUserAuthenticator 不适合一般使用,因此不要将其注册在核心 Security 类下!

启用 CORS

要使用 JWT,需要启用 CORS。这可以通过将以下内容添加到您的配置 .yml 来实现。

SilverStripe\GraphQL\Controller:
  cors:
    Enabled: true
    Allow-Origin: "*"
    Allow-Headers: "Authorization, Content-Type"
    Allow-Methods: "GET, POST, OPTIONS"
    Max-Age: 86400 # ...in seconds

使用方法

登录后,您将收到一个令牌,可用于后续请求。此令牌应作为请求头的签名 Bearer

Authorization: Bearer [token]

前缀

可以将前缀与 JWT 记录的唯一标识符关联。这可以更容易地区分在不同上下文中创建的 JWT 记录,例如特定域名或环境类型。这不是出于安全目的的必要条件。

JWT_PREFIX="[your secret prefix]"

安全

目前,加密JWT的默认方法是使用SHA256。JWT使用多个因素进行签名,包括主机、受众(应用/远程用户)、密钥以及一个令牌有效的有效期限。同一时间只能有一个设备登录。

支持的服务

默认情况下,JWT仅支持登录。由于它的令牌不能被禁用,也不能用于密码更改或重置。

注意事项

当在Apache下使用CGI/FastCGI模式下的PHP时,Authorization头可能无法正常工作,请参阅问题#15。解决方案很简单,只需在您的.htaccess文件中添加SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0参考)。

示例

Postman集合可以在extra文件夹中找到。

牛?

当然!

               /( ,,,,, )\
              _\,;;;;;;;,/_
           .-"; ;;;;;;;;; ;"-.
           '.__/`_ / \ _`\__.'
              | (')| |(') |
              | .--' '--. |
              |/ o     o \|
              |           |
             / \ _..=.._ / \
            /:. '._____.'   \
           ;::'    / \      .;
           |     _|_ _|_   ::|
         .-|     '==o=='    '|-.
        /  |  . /       \    |  \
        |  | ::|         |   | .|
        |  (  ')         (.  )::|
        |: |   |;  U U  ;|:: | `|
        |' |   | \ U U / |'  |  |
        ##V|   |_/`"""`\_|   |V##
           ##V##         ##V##