RemixJS, Cloudflare Pages 專案使用 Google Sign-in
承上篇的環境設定,要使用 Google sign-in 但不使用官方套件 google-auth-library
。
可以使用 worker-auth-providers,它雖然還在 beta 版,但簡單的 oauth 登入是可行的。
GCP 基本設定
Google Cloud Platform (GCP) 設定並下載憑證資料:
-
到「API 程式庫」>「公開」>「社交」啟用 Google People API。
-
到「API和服務 > 憑證」,點選「+建立憑證」>「OAuth 用戶 ID」。
-
「應用程式類型」選「網頁應用程式」
-
「已授權的 JavaScript 來源」加入正式環境及測試環境的 URI。
-
「已授權的重新導向 URI」加入接收 Query String 參數的頁面 URI,同樣包含測試及正式環境。
-
建立完成後,「下載 OAuth 用戶端」的 JSON 檔。
-
到「OAuth 同意畫面」,設定應用程式名稱,及測試帳號等。
登入頁面
按了「Google 登入」的按鈕轉到 google-signin.tsx
頁面
// app/routes/google-signin.tsx
import { type LoaderFunctionArgs, redirect } from "@remix-run/cloudflare";
import { google } from "worker-auth-providers";
import { getMySession } from "~/utils/sessions";
export async function loader({ request, context, params }: LoaderFunctionArgs) {
const session = await getMySession(request);
const userId = session.get("userId");
if (userId) {
return redirect("/");
}
const env: any = context.env;
const googleLoginUrl = await google.redirect({
options: {
clientId: env.GOOGLE_CLIENT_ID,
redirectTo: env.GOOGLE_REDIRECT_URI,
},
});
return redirect(googleLoginUrl);
}
用戶登入後轉向的頁面
//
import { type LoaderFunctionArgs, redirect } from "@remix-run/cloudflare";
import { getMySession, getHeadersWithSetCookie } from "~/utils/sessions";
import { google } from "worker-auth-providers";
import getSupabase from "~/utils/supabase-client";
export async function loader({ request, context, params }: LoaderFunctionArgs) {
const env: any = context.env;
const { user, tokens } = await google.users({
options: {
clientSecret: env.GOOGLE_CLIENT_SECRET,
clientId: env.GOOGLE_CLIENT_ID,
redirectUrl: env.GOOGLE_REDIRECT_URI,
},
request,
});
// "user": {
// "id": "111******",
// "email": "shinder.lin@gmail.com",
// "verified_email": true,
// "name": "Shinder Lin",
// "given_name": "Shinder",
// "family_name": "Lin",
// "picture": "...",
// "locale": "zh-TW"
// },
// console.log({ user, tokens });
// tokens: {
// access_token: 'ya29...',
// expires_in: 3599,
// scope: 'https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile openid',
// token_type: 'Bearer',
// id_token: 'eyJh...'
// }
if (!user?.id) {
return redirect("/login");
}
const supabase = getSupabase(context);
const { data: data1, error: error1 } = await supabase
.from("g_users")
.select()
.eq("gid", user.id);
// 是否已經登入過
if (data1.length) {
const row: any = data1[0];
if (row.blocked) {
return { msg: "您的帳號已被停權" };
} else {
await supabase
.from("g_users")
.update({ updated_at: new Date() })
.eq("gid", row.gid);
}
} else {
const { data: data2, error: error2 } = await supabase
.from("g_users")
.insert({ gid: user.id, email: user.email, name: user.name })
.select();
if (!data2.length) {
return { msg: "DB 無法新增資料" };
}
}
const session = await getMySession(request);
session.set("gid", user.id);
session.set("userId", user.email);
session.set("nickname", user.name);
const headers = await getHeadersWithSetCookie(session);
return redirect('/', { headers });
}
沒有留言:
張貼留言