今天要來寫註冊的 GraphQL API,以及註冊時,都會有密碼,密碼的部份,會使用 bcrypt 雜湊演算法來加密。
這邊會避免過多的邏輯判斷,所以就先著重在 GraphQL API 的建立、密碼的加密,能存進資料庫即可。
在 webmix_api 資料夾下,更新 typedefs.ts 檔案,內容如下:
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(nickname: String!, email: String!, password: String): User!
updateUser(id: Int!, firstname: String!, lastname: String!): User!
deleteUser(id: Int!): Boolean!
authUser(username: String!, password: String!): String!
}
type User {
id: ID!
role_id: Int!
nickname: String!
email: String!
}
`;
註冊的 API,就是 insertUser 那行。所以接下來就要實作 insertUser。
在 webmix_api 資料夾下,更新 resolvers.ts 檔案,該檔的最上方,加以下這行,也就是要用 bcrypt 來加密:
import * as bcrypt from "https://deno.land/x/bcrypt@v0.4.0/mod.ts";
然後 insertUser 函式,實作如下:
async function insertUser(args){
// 加密
const salt = await bcrypt.genSalt(8);
const password_hash = await bcrypt.hash(args.password, salt);
let result = await client.execute(`INSERT INTO users(role_id, nickname, email, password, created_at) values(2, '${args.nickname}', '${args.email}', '${password_hash}', ${Date.now()})`);
let getInsertedUser = await client.query("select * from ?? where id = ?", ["users", result.lastInsertId]);
return getInsertedUser[0];
}
加密的部份,就是產生一個 salt(每次註冊時,所用的 salt 都不一樣),然後「使用者的密碼 + salt」,經過 bcrypt 的雜湊演算法,就產生了加密後的密碼,將之存在資料庫即可。
一樣開啟,GraphQL API 的執行環境,輸入以下範例:
mutation {
insertUser(nickname: "carlos", email: "a@gmail.com", password: "abcd1234"){
id
role_id
nickname
email
}
}
回傳結果如下圖:
資料庫中新增的示意圖,也可以看一下,的確有新增資料成功,密碼也有加密:
加密有的網站還會最後再經過 AES 加密,層層把關。
然後如果是正式的網站,關於個資的部份(例:email),也應該使用加解密演算法來進行加密,這邊就著重在密碼的部份囉。
又往前邁進一步了,太好了,有了 API,那麼 Vue 做的網站,就可以來串接這個註冊的 API 了。