iT邦幫忙

2022 iThome 鐵人賽

DAY 13
0
Modern Web

使用 Vue 3 從 0 到 1 架設網站!!!系列 第 13

寫一個 GraphQL API,回傳 JSON Web Tokens(JWT)

  • 分享至 

  • xImage
  •  

這邊呢,其實我先忽略註冊、登入密碼驗證。

主要先著重在我初次使用的產生 JWT 這樣的機制。

GraphQL 的 Schema 定義

在 webmix_api 資料夾下,有 typedefs.ts 檔案,加一行:

authUser(username: String!, password: String!): String!

原始碼不多,所以直接整個附上:

import { gql } from "https://deno.land/x/graphql_tag@0.0.1/mod.ts";

export const typeDefs = gql`
  type Query {
    hello: String
    allUsers: [User!]!
  }

  type Mutation {
    insertUser(firstname: String!, lastname: String!): User!
    updateUser(id: Int!, firstname: String!, lastname: String!): User!
    deleteUser(id: Int!): Boolean!
    authUser(username: String!, password: String!): String!
  }

  type User {
    id: ID!
    firstname: String!
    lastname: String!
  }
`;

GraphQL 的 Resolver 解析 authUser

在 webmix_api 資料夾下,有 resolvers.ts 檔案,最上方加一行:

import { create, verify, decode, getNumericDate } from "https://deno.land/x/djwt@v2.7/mod.ts";

這個套件的官網是這個,也就是接下來的 authUser 函式會用到,就是用來產生 JWT 的套件。

繼續更新 resolvers.ts 檔案,加以下的函式:

async function authUser(args){
  // 產生 key
  const key = await crypto.subtle.generateKey(
    { name: "HMAC", hash: "SHA-256" },
    true,
    ["sign", "verify"],
  );
  //console.log(key)

  // 產生 jwt
  let jwt = await create({ alg: "HS256", typ: "JWT" }, {username: args.username, role: "user", exp: getNumericDate(60 * 60)}, key)
  //console.log("jwt: " + jwt)

  return jwt
}

這個 authUser 函式呢,裡面有執行到 create 函式,其中所帶的參數,分別就是產生 HEADER、PAYLOAD、SIGNATURE 所需要的資料,然後 create 函式最後就是會回傳 JWT。

然後在 resolvers 常數的部份,完整程式如下(主要就是加 authUser 那行):

export const resolvers = {
  Query: {
    hello: () => `Hello World!`,
    allUsers: () => allUsers()
  },
  Mutation: {
    insertUser: (_: any, args: any) => insertUser(args),
    updateUser: (_: any, args: any) => updateUser(args),
    deleteUser: (_: any, args: any) => deleteUser(args),
    authUser: (_: any, args: any) => authUser(args)
  }
};

這樣就寫完了,可以測試看看是否可以取得 JWT。

使用 GraphQL 執行環境

開啟 GraphQL 的執行環境,執行以下的 mutation:

mutation {
  authUser(username: "測試取得jwt", password: "ss")
}

如下示意圖:

https://ithelp.ithome.com.tw/upload/images/20220913/20069901ikJSR2bKoP.png

回傳的範例 JWT,如下:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Iua4rOippuWPluW-l2p3dCIsInJvbGUiOiJ1c2VyIiwiZXhwIjoxNjYzMDAzODUwfQ.l1lNWxR3dSx98PO_hNDsK36ccwf6JFpRbiWNDwWtq6c

當然也可以寫程式,將資料轉回來取出,但可以先用 JWT 線上工具測試一下,也就是將以上的 JWT 複製下來,然後丟到線上工具,如下圖示意:

https://ithelp.ithome.com.tw/upload/images/20220913/20069901HcO0x8vd78.png

的確有得到解析的結果了,當然也可以知道一件事情,不要將機密資訊存至 JWT 喔。

結語

覺得很不錯,有產生 JWT 且使用 GraphQL API 的機制。
所以登入的流程一般來說,就是帳密如果驗證通過,然後再產生 JWT 回傳給前端。


上一篇
登入機制驗證,淺談 JSON Web Tokens(JWT)
下一篇
Vite + Vue3 建立頁面 - 首頁微調、建立註冊頁面、規劃註冊流程
系列文
使用 Vue 3 從 0 到 1 架設網站!!!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言