這邊呢,其實我先忽略註冊、登入密碼驗證。
主要先著重在我初次使用的產生 JWT 這樣的機制。
在 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!
}
`;
在 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 的執行環境,執行以下的 mutation:
mutation {
authUser(username: "測試取得jwt", password: "ss")
}
如下示意圖:
回傳的範例 JWT,如下:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Iua4rOippuWPluW-l2p3dCIsInJvbGUiOiJ1c2VyIiwiZXhwIjoxNjYzMDAzODUwfQ.l1lNWxR3dSx98PO_hNDsK36ccwf6JFpRbiWNDwWtq6c
當然也可以寫程式,將資料轉回來取出,但可以先用 JWT 線上工具測試一下,也就是將以上的 JWT 複製下來,然後丟到線上工具,如下圖示意:
的確有得到解析的結果了,當然也可以知道一件事情,不要將機密資訊存至 JWT 喔。
覺得很不錯,有產生 JWT 且使用 GraphQL API 的機制。
所以登入的流程一般來說,就是帳密如果驗證通過,然後再產生 JWT 回傳給前端。