[Sleact]ゆったりパンツクローンコード-ログイン



ログインページ


pages/Login/index.tsx
import useInput from '@hooks/useInput';
import { Success, Form, Error, Label, Input, LinkContainer, Button, Header } from '@pages/SignUp/styles';
// import fetcher from '@utils/fetcher';
import axios from 'axios';
import React, { useCallback, useState } from 'react';
import { Link, Redirect } from 'react-router-dom';
import useSWR from 'swr';

const LogIn = () => {
  const [logInError, setLogInError] = useState(false);
  const [email, onChangeEmail] = useInput('');
  const [password, onChangePassword] = useInput('');
  const onSubmit = useCallback(
    (e) => {
      e.preventDefault();
      setLogInError(false);
      // 프록시 설정을 껐다
      axios
        .post('http://localhost:3095/api/users/login', { email, password }, { withCredentials: true })
        .then(() => {})
        .catch((error) => {
          setLogInError(error.response?.data?.statusCode === 401);
        });
    },
    [email, password],
  );

  return (
    <div id="container">
      <Header>Sleact</Header>
      <Form onSubmit={onSubmit}>
        <Label id="email-label">
          <span>이메일 주소</span>
          <div>
            <Input type="email" id="email" name="email" value={email} onChange={onChangeEmail} />
          </div>
        </Label>
        <Label id="password-label">
          <span>비밀번호</span>
          <div>
            <Input type="password" id="password" name="password" value={password} onChange={onChangePassword} />
          </div>
          {logInError && <Error>이메일과 비밀번호 조합이 일치하지 않습니다.</Error>}
        </Label>
        <Button type="submit">로그인</Button>
      </Form>
      <LinkContainer>
        아직 회원이 아니신가요?&nbsp;
        <Link to="/signup">회원가입 하러가기</Link>
      </LinkContainer>
    </div>
  );
};

export default LogIn;

ログイン後、クッキーを次のように表示できます.終了はこのクッキーをクリアすることに等しい.では、フロントの角度から、私が登録に成功したことをどうして知っていますか?

ログインリクエストが成功した場合は、サーバからフロントに私の情報を送信し、保存してログアウト時に破棄できます.
ログイン情報を保存するには、グローバルデータとして保存する必要があります.このプロジェクトでは、Ridexではなく、SWRを使用します.

SWRの使用


pages/LogIn/index.tsx
const LogIn = () => {
  const { data, error } = useSWR('http://localhost:3095/api/users', fetcher);
  ...
}
useSWR自体には何の機能もなく、urlfetcher関数に渡す.このfetcher関数は、utils/fetcher.tsファイルを生成し、そこで管理する.
utils/fetcher.ts
import axios from 'axios';

const fetcher = (url: string) => axios.get(url).then((response) => response.data);

export default fetcher;

こうしてログインに成功しました.
users要求はログイン情報を含まない.これは,フロントエンドサーバアドレスとバックエンドサーバアドレスが異なるため,Cookieを渡すことができないためである.フロントエンドサーバとバックエンドサーバのドメインが異なる場合、バックエンドサーバはフロントエンドサーバに対してCookieを生成することができず、フロントエンドからバックエンドにCookieを送信することもできない.
この問題を解決する設定はwithCredentialsの属性である.
utils/fetcher.ts
import axios from 'axios';

const fetcher = (url: string) => axios.get(url, { withCredentials: true }).then((response) => response.data);

export default fetcher;
pages/LogIn/index.tsx
const LogIn = () => {
  const { data, error } = useSWR('http://localhost:3095/api/users', fetcher);
  const [logInError, setLogInError] = useState(false);
  const [email, onChangeEmail] = useInput('');
  const [password, onChangePassword] = useInput('');
  const onSubmit = useCallback(
    (e) => {
      e.preventDefault();
      setLogInError(false);
      axios
        .post('http://localhost:3095/api/users/login', { email, password }, { withCredentials: true })
        .then(() => {})
        .catch((error) => {
          setLogInError(error.response?.data?.statusCode === 401);
        });
    },
    [email, password],
  );
  ...
}
get要求の第2の位置、post要求の第3の位置はwithCredentials属性を含むことができる.


その後、このようにクッキーが正常に生成されていることが確認される.Cookieは常にバックグラウンドで生成され、フロントブラウザに格納され、フロントが要求するたびに覚えたCookieがバックグラウンドに送信されます.

SWR設定の表示

SWRを使用中にエラーが発生し、ハッカーになる可能性があります.これはセルフDDOS攻撃で、それを防ぐために設定できます.
まず、revalidateを使用して、revalidateのたびにこの要求を実行することができる.また、要求周期は、dedupingIntervalの設定により調整することができる.
const LogIn = () => {
  const { data, error, revalidate } = useSWR('http://localhost:3095/api/users', fetcher, { dedupingInterval: 100000 });
  ...
  const onSubmit = useCallback(
    (e) => {
      e.preventDefault();
      setLogInError(false);
      axios
        .post('http://localhost:3095/api/users/login', { email, password }, { withCredentials: true })
        .then(() => {
          revalidate();
        })
        .catch((error) => {
          setLogInError(error.response?.data?.statusCode === 401);
        });
    },
    [email, password],
  );
  ...
}
より詳細な方法は、SWRドキュメントにあります.