Closed4
Astro 3 + cloudflare Pages + D1, ログイン認証の追加
概要
cloudflare pages + Astro ログイン認証の追加メモになります
- wranglerで、デプロイする方法になります
- crypto-js 使います
- API Serverは、workers + D1の構成です。
- D1(アルファ版) 使います
環境
- Astro 3
- cloudflare pages
- cloudflare D1
- React
- TailwindCSS
- crypto-js
作成したコード
- API
- package.json
{
"name": "astro3_4cf",
"type": "module",
"version": "0.0.1",
"scripts": {
"dev": "astro dev",
"start": "astro dev",
"build": "astro build",
"build-css": "npx tailwindcss -i ./src/input.css -o ./public/styles/output.css",
"preview": "astro preview",
"astro": "astro"
},
"dependencies": {
"@astrojs/cloudflare": "^7.0.1",
"@astrojs/react": "^3.0.0",
"@astrojs/tailwind": "^5.0.0",
"@types/react": "^18.2.21",
"@types/react-dom": "^18.2.7",
"astro": "^3.0.7",
"crypto-js": "^4.1.1",
"moment": "^2.29.4",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"tailwindcss": "^3.3.3",
"wrangler": "^3.6.0"
}
}
- pages/user/create.astro
import Layout from '../../layouts/Layout.astro';
export type Post = {
id: number;
name: string;
};
//
---
<Layout title="Welcome to Astro.">
<div class="container_base">
<div class="py-4">
<a href={`/`} >[ Back ]</a>
</div>
<hr />
<h1 class="text-4xl font-bold">User-Create</h1>
<hr />
<div class="col-sm-6">
<div>
<label class="text-2xl block text-gray-700 font-bold mb-2">Name:
</label>
<input type="text" class="input_text" name="name" id="name" />
<label class="text-2xl block text-gray-700 font-bold mb-2">Email:
</label>
<input type="text" class="input_text" name="email" id="email" />
<br />
<label class="text-2xl block text-gray-700 font-bold mb-2">Password:
</label>
<input type="password" class="input_text" name="password" id="password" />
<button id="btn_save" class="btn my-2">Save
</button>
</div>
</div>
</Layout>
<!-- -->
<style>
</style>
<!-- -->
<script src="./CrudCreate.ts"></script>
- pages/user/CrudCreate.ts
- crypto-jsで、暗号化します
CrudCreate.ts
import LibConfig from '../../lib/LibConfig';
import LibCrypto from '../../lib/LibCrypto'
//
const CrudCreate = {
/**
* addItem:
* @param key: any
*
* @return
*/
addItem : async function() : Promise<any>
{
try{
let ret = false;
const name = document.querySelector<HTMLInputElement>('#name');
const password = document.querySelector<HTMLInputElement>('#password');
const email = document.querySelector<HTMLInputElement>('#email');
let passwordValue = "";
if(password) { passwordValue = password?.value; }
const hashedPassword = LibCrypto.encode(passwordValue);
const item = {
name: name?.value,
email: email?.value,
password: hashedPassword,
"api_key": import.meta.env.PUBLIC_API_KEY,
path: "/users/create",
}
//console.log(item);
const body = JSON.stringify(item);
const res = await fetch("/api/user/create", {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: body
});
const json = await res.json()
console.log(json);
if (res.status !== 200) {
throw new Error(await res.text());
}
if (json.ret === LibConfig.OK_CODE) {
ret = true;
}
return ret;
} catch (e) {
console.error(e);
throw new Error('Error , addItem');
}
},
/**
* startProc
* @param
*
* @return
*/
startProc :async function (): Promise<void>
{
try{
//btn
const button: any = document.querySelector('#btn_save');
button.addEventListener('click', async () => {
const result = await this.addItem();
console.log("result=", result);
if(result) {
window.location.href = '/login';
} else {
alert("Error, user create");
}
});
} catch (e) {
console.error(e);
}
}
}
//
CrudCreate.startProc();
export default CrudCreate;
- pages/login/index.astro
<Layout title="Welcome to Astro.">
<div class="container_base my-2 pb-8">
<a href={`/`}>[ Top ]</a>
<hr />
<h1 class="text-4xl font-bold">Login</h1>
<hr />
<div class="">
<label class="text-2xl block text-gray-700 font-bold mb-2">Email:
</label>
<input type="text" class="input_text" name="email" id="email" />
<br />
<label class="text-2xl block text-gray-700 font-bold mb-2">Password:
</label>
<input type="password" class="input_text" name="password" id="password" />
<hr />
<button id="btn_login" class="btn my-2">Login</button>
</div>
<hr class="my-2" />
<a href={`/user/create`}>[ User Create ]</a>
</div>
</Layout>
- Login.ts
- COOKIE に、user data保存します
Login.ts
login : async function() : Promise<any>
{
try{
let ret = false;
const password = document.querySelector<HTMLInputElement>('#password');
const email = document.querySelector<HTMLInputElement>('#email');
let passwordValue = "";
if(password) { passwordValue = password?.value; }
let postItem = {
"name": "a1",
"email": email?.value,
"api_key": import.meta.env.PUBLIC_API_KEY,
}
console.log("passwordValue=", passwordValue);
const json = await HttpCommon.server_post(postItem, "/users/get");
//console.log(json);
if (json.ret !== LibConfig.OK_CODE) {
console.error("Error,json.ret <> OK");
alert("Error");
return;
}
const user = json.data;
const decryptPassword = LibCrypto.decode(user.password);
if(passwordValue !== decryptPassword){
console.error("Error, password is NG");
alert("Error, login");
return;
}
console.log("Success, auth");
const key = LibConfig.COOKIE_KEY_AUTH;
await LibCookie.set_cookie(key, user.id);
location.href = '/';
return ret;
} catch (e) {
console.error(e);
throw new Error('Error , login');
}
},
関連のページ
このスクラップは2023/09/08にクローズされました