次の認証.ファイアーベース
38116 ワード
私の次に.JSプロジェクト、私はいくつかの認証を追加したい.私のユーザー管理とデータストアのFireBaseを使用することを決めた.
必要なもの さえずりを使ったOAuth クライアント側認証 保護ページ サーバ側認証
セットアップfirebase
firebaseパッケージのインストール
Authフックのビルド
私は、auth状態を扱うために文脈APIを使用することに決めました.この方法で簡単に任意のアプリケーションの全体の変数にアクセスできます.
まず、私は
それからフックのコンテキスト部分を設定します
Authフックの使用
追加
私たちはボタンにサインを追加することができます
サーバ側認証
サーバー側認証はクライアントからAPIへのIDトークンを渡すことによって扱われます.その後、APIはすべてのリクエストでトークンを確認します.
最初にトークンを渡すフェッチUtilを作成しましょう.
APIルート:
結論
私は今、FireBaseを使用して自分のWebアプリケーションの認証を行っている. ユーザーはTwitterのOAuthを使用してログインできます. これは、ユーザーを作成し、FireBaseに格納します. 私は、ユーザーが認証されないなら、リダイレクトを持った保護されたルートを持っています. 私は、これまでのリクエストでユーザーのトークンを検証する保護されたエンドポイントを持っています. ここではRepository 記事の作業コードを使用します.
それは最高の解決策ではないかもしれないが、仕事を得る. ネスト.jsDocs
火の粉Docs
SWRDocs
技術とプログラミングについてのランダムなポストのために私に続いてください.私も私の旅の学習デザインのドキュメントです.
必要なもの
Assumptions: You already have a base Next.js project setup and you created a project in Firebase.
セットアップfirebase
firebaseパッケージのインストール
npm i --save firebase firebase-admin
クリエイトアenv.local
ファイルを必要なすべてのfirebaseキーを追加するNEXT_PUBLIC_FIREBASE_API_KEY=********************
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=***********
NEXT_PUBLIC_FIREBASE_PROJECT_ID=*********
FIREBASE_PRIVATE_KEY=*********************
FIREBASE_CLIENT_EMAIL=*************
FIREBASE_DATABASE_URL=*************
ここでFireBaseに接続するファイルを作成する必要があります.lib/firebase.ts
- OAuthの処理と認証の維持import * as firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/functions';
import 'firebase/firestore';
if (!firebase.apps.length) {
firebase.initializeApp({
apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID
});
}
export default firebase;
lib/firebase-admin.ts
- トークンサーバー側の確認.import admin from 'firebase-admin';
if (!admin.apps.length) {
admin.initializeApp({
credential: admin.credential.cert({
projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
privateKey: process.env.FIREBASE_PRIVATE_KEY,
clientEmail: process.env.FIREBASE_CLIENT_EMAIL
}),
databaseURL: process.env.FIREBASE_DATABASE_URL
});
}
const db = admin.firestore();
const auth = admin.auth();
export { db, auth };
lib/db.ts
- データベースクエリimport firebase from '../lib/firebase';
const firestore = firebase.firestore();
export function updateUser(uid: string, data: any) {
return firestore.collection('users').doc(uid).update(data);
}
export function createUser(uid: string, data: any) {
return firestore
.collection('users')
.doc(uid)
.set({ uid, ...data }, { merge: true });
}
今、我々は簡単に我々のユーザーのセッションとauth状態を維持するためのフックを構築するためにこれらのlibファイルを使用することができます.Authフックのビルド
私は、auth状態を扱うために文脈APIを使用することに決めました.この方法で簡単に任意のアプリケーションの全体の変数にアクセスできます.
まず、私は
lib/auth.tsx
.それからフックのコンテキスト部分を設定します
interface AuthContext {
auth: Auth | null;
loading: boolean;
signInWithTwitter: () => Promise<void>;
signOut: () => Promise<void>;
}
// Create context with a default state.
const authContext: Context<AuthContext> = createContext<AuthContext>({
auth: null,
loading: true,
signInWithTwitter: async () => {},
signOut: async () => {}
});
export function AuthProvider({ children }) {
const auth = useProvideAuth();
return <authContext.Provider value={auth}>{children}</authContext.Provider>;
}
// Helper to easily get auth context within components
export const useAuth = () => useContext(authContext);
より複雑な部分のための時間useProvideAuth()
.function useProvideAuth() {
const [auth, setAuth] = useState<Auth | null>(null);
const [loading, setLoading] = useState<boolean>(true);
/**
* Callback function used for firebase.auth.onAuthStateChanged().
* Takes the user object returned and formats it for my state.
* We fetch the idToken and append it to my auth state and store it.
*/
const authStateChanged = async (authState: firebase.User | null) => {
// Formats response into my required state.
const formattedAuth = formatAuth(authState);
// Fetch firebase auth ID Token.
formattedAuth.token = await authState.getIdToken();
// Stores auth into state.
setAuth(formattedAuth);
// Sets loading state to false.
setLoading(false);
};
/**
* Callback function used for response from firebase OAuth.
* Store user object returned in firestore.
* @param firebase User Credential
*/
const signedIn = async (resp: firebase.auth.UserCredential) => {
// Format user into my required state.
const storeUser = formatAuth(resp.user);
// firestore database function
createUser(storeUser.uid, storeUser);
};
/**
* Callback for when firebase signOut.
* Sets auth state to null and loading to true.
*/
const clear = () => {
setAuth(null);
setLoading(true);
};
/**
* Triggers firebase Oauth for twitter and calls signIn when successful.
* sets loading to true.
*/
const signInWithTwitter = () => {
setLoading(true);
return firebase.auth().signInWithPopup(new firebase.auth.TwitterAuthProvider()).then(signedIn);
};
/**
* Calls firebase signOut and with clear callback to reset state.
*/
const signOut = () => {
return firebase.auth().signOut().then(clear);
};
/**
* Watches for state change for firebase auth and calls the handleUser callback
* on every change.
*/
useEffect(() => {
const unsubscribe = firebase.auth().onAuthStateChanged(authStateChanged);
return () => unsubscribe();
}, []);
// returns state values and callbacks for signIn and signOut.
return {
auth,
loading,
signInWithTwitter,
signOut
};
}
Authフックの使用
追加
AuthProvider
私にpages/_app.tsx
.import { AppProps } from 'next/app';
import { AuthProvider } from '../lib/auth';
import '../styles/globals.css';
export default function MyApp({ Component, pageProps }: AppProps) {
return (
<AuthProvider>
<Component {...pageProps} />
</AuthProvider>
);
}
今、我々はAuthContext
我々のページで.私たちはボタンにサインを追加することができます
pages/index.tsx
. 我々が認証されるならば、我々はリンクとサインアウトボタンを表示することができます.import { useAuth } from '../lib/auth';
import Link from 'next/link';
import { useEffect } from 'react';
export default function Home() {
const { auth, signOut, signInWithTwitter } = useAuth();
return (
<div>
{auth ? (
<div>
<Link href='/dashboard'>
<a>Dashboard</a>
</Link>
<button onClick={() => signOut()}>Sign Out</button>
</div>
) : (
<button onClick={() => signInWithTwitter()}>Sign In</button>
)}
</div>
);
}
私のダッシュボードルートをAuthで保護したい.ユーザーが認証されていない場合、インデックスページにリダイレクトされます.import { useRouter } from 'next/router';
import { useEffect } from 'react';
import { useAuth } from '../lib/auth';
export default function Dashboard() {
const { auth, loading, signOut } = useAuth();
const router = useRouter();
useEffect(() => {
// If auth is null and we are no longer loading
if (!auth && !loading) {
// redirect to index
router.push('/');
}
}, [auth, loading]);
return (
<div>
<p>Dashboard: Hello World</p>
{auth && (
<div>
<button onClick={() => signOut()}>Sign Out</button>
</div>
)}
</div>
);
}
サーバ側認証
サーバー側認証はクライアントからAPIへのIDトークンを渡すことによって扱われます.その後、APIはすべてのリクエストでトークンを確認します.
最初にトークンを渡すフェッチUtilを作成しましょう.
util/fetcher.ts
.const fetcher = async (url: string, token: string) => {
const res = await fetch(url, {
method: 'GET',
headers: new Headers({ 'Content-Type': 'application/json', token }),
credentials: 'same-origin'
});
return res.json();
};
export default fetcher;
その後、APIルート上のトークンを確認することができますfirebase-admin
.APIルート:
pages/api/user.ts
import { NextApiRequest, NextApiResponse } from 'next';
import { auth } from '../../lib/firebase-admin';
export default async (req: NextApiRequest, res: NextApiResponse) => {
try {
const { uid } = await auth.verifyIdToken(req.headers.token);
res.status(200).json({ uid });
} catch (error) {
res.status(401).json({ error });
}
};
これで、ダッシュボードページ内のユーザーデータを取得するAPI呼び出しを行うことができます.私はuseSWR
API呼び出しを扱うフック.pages/dashboard.tsx
import { useRouter } from 'next/router';
import { useEffect } from 'react';
import useSWR from 'swr';
import { useAuth } from '../lib/auth';
import fetcher from '../util/fetcher';
export default function Dashboard() {
const { auth, loading, signOut } = useAuth();
const router = useRouter();
useEffect(() => {
if (!auth && !loading) {
router.push('/');
}
}, [auth, loading]);
const { data } = useSWR(auth ? ['/api/user', auth.token] : null, fetcher);
return (
<div>
<p>Dashboard: Hello World</p>
{auth && (
<div>
<button onClick={() => signOut()}>Sign Out</button>
</div>
)}
{data && <div>{data}</div>}
</div>
);
}
結論
私は今、FireBaseを使用して自分のWebアプリケーションの認証を行っている.
それは最高の解決策ではないかもしれないが、仕事を得る.
Reference
この問題について(次の認証.ファイアーベース), 我々は、より多くの情報をここで見つけました https://dev.to/codebycorey/authentication-for-next-js-using-firebase-2i8hテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol