React+AWS Cognito教程二:Cognito Session及用户登出


在上篇文章介绍了如何注册,配置AWS Cognito User Pool及用户登录,下面介绍Cognito中的Session,及如何注销用户的登录。

AWS Cognito
AWS Cognito

声明:本教程代码参考了Alexzander Flores的代码并在其基础上进行了修改和优化。

AWS Cognito系列教程:

将登录,登出及Session操作封装到Accounts.js中

创建components/Accounts.js

javascript
import React, { createContext } from 'react';
import { CognitoUser, AuthenticationDetails } from 'amazon-cognito-identity-js';
import Pool from './UserPool';

const AccountContext = createContext();

const Account = props => {
  const getSession = async () =>
    await new Promise((resolve, reject) => {
      const user = Pool.getCurrentUser();
      if (user) {
        user.getSession((err, session) => {
          if (err) {
            reject();
          } else {
            resolve(session);
          }
        });
      } else {
        reject();
      }
    });

  const authenticate = async (Username, Password) =>
    await new Promise((resolve, reject) => {
      const user = new CognitoUser({ Username, Pool });
      const authDetails = new AuthenticationDetails({ Username, Password });

      user.authenticateUser(authDetails, {
        onSuccess: data => {
          console.log('onSuccess:', data);
          resolve(data);
        },

        onFailure: err => {
          console.error('onFailure:', err);
          reject(err);
        },

        newPasswordRequired: data => {
          console.log('newPasswordRequired:', data);
          resolve(data);
        }
      });
    });
  
  const logout = () => {
    const user = Pool.getCurrentUser();
    if (user) {
      user.signOut();
    }
  }

  return (
    <AccountContext.Provider value={{
      authenticate,
      getSession,
      logout
    }}>
      {props.children}
    </AccountContext.Provider>
  );
};

export { Account, AccountContext };

修改Login.js

有了Accounts.js的封装,就可以优化Login.js的代码了:

javascript
import { useRef, useContext } from 'react';
import { AccountContext } from './Accounts';

export default function Login() {
  const emailElement = useRef('');
  const passwordElement = useRef('');
  const { authenticate } = useContext(AccountContext);

  const handleSubmit = e => {
    e.preventDefault();

    authenticate(emailElement.current.value, passwordElement.current.value)
      .then(data => {
        console.log('Logged in!', data);
      })
      .catch(err => {
        console.error('Failed to login!', err);
    })
  }

  return (
    <div className="App">
      <form onSubmit={handleSubmit}>
        Email: 
        <input type="text" ref={emailElement}/><br/>
        Password: 
        <input type="text" ref={passwordElement}/><br/>
        <button type="submit">Login</button>
      </form>
    </div>
  );
}

封装Status.js

javascript
import React, { useState, useContext, useEffect } from 'react';
import { AccountContext } from './Accounts';

export default function Status() {
  const [status, setStatus] = useState(false);

  const { getSession, logout } = useContext(AccountContext);

  useEffect(() => {
    getSession()
      .then(session => {
        console.log('Session:', session);
        setStatus(true);
      })
      // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  return (
    <div>
      {status ? (
        <div>
          You are logged in.
          <button onClick={logout}>Logout</button>
        </div>
      ) : 'Please login below.'}
    </div>
  );
};

修改App.js

javascript
import Signup from "./components/Signup";
import Login from './components/Login';
import Status from './components/Status';
import { Account } from './components/Accounts';

function App() {
  return (
    <Account>
      <Status/>
      <Signup/>
      <Login/>
    </Account>
  );
}

export default App;

在登录后查看浏览器控制台,可以看到,其实Cognito是在使用JWT来管理Sesssion:

AWS Cognito
AWS Cognito


文章作者: 逻思
版权声明: 本博客所有文章除特別声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明来源 逻思 !