ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • React로 블로그 만들기 #8
    2018~2019/React.js 2018. 11. 4. 23:44

    React로 블로그 만들기 #8

     - 로그인 구현(5) 새로고침 후 로그인 유지 -


    1. 로그인 유지

    - 로그인을 한다고 해도 자동으로 로그인 상태가 유지되지 않는다.
    - 브라우저를 닫거나 새로고침할 시 스토어 값이 초기화되므로 페이지에 다시 들어왔을 때 로그인을 유지하는 로직이 필요하다.

    - TodoApp에서는 쿠키를 이용하여 로그인을 유지하였지만, 블로그 앱에서는 HTML5에서 제공하는Web Storage API를 사용한다.

    - 또한 로그아웃 시 소셜로그인으로 발급받은 토큰을 제거하도록 로직을 추가해야함.


    2. localStorage vs sessionStorage

    - Key와 Value 값으로 저장.

    - 문자열이 아닌 객체도 저장이 가능하며 5MB까지 저장 가능함.

    - 쿠키와 다르게 만료기간을 지정할 수 없으며, 서버로 전송되지 않음.

    - 자동로그인을 원하면 localStorage를 사용하고 브라우저를 닫으면 로그인이 풀리는 것을 원하면 sessionStorage를 사용


    1) localStorage

    - 사용자가 지우지 않는 이상 영구적으로 계속 브라우저에 남아있음.

    - 따라서 지속적으로 필요한 정보를 저장한다. (자동로그인 등)


    2) sessionStorage

    - 윈도우나 브라우저를 닫는 경우 사라지며 뿐만 아니라 브라우저 내에서 탭을 생성하는 경우에도 별도의 영역으로 할당됨.

    - 잠시동안 필요한 정보를 저장한다. (일회성 로그인 등)


    3. 구현하기

    1) src/Components/Login.js

    - 소셜로그인 성공 시 받은 정보를 세션스토리지에 저장함.

    import React, { Component } from 'react';
    import { GoogleLogin } from 'react-google-login';
    import KakaoLogin from 'react-kakao-login';
    import styled from 'styled-components';
    import { withRouter } from "react-router-dom";

    class Login extends Component {

    constructor(props) {
    super(props);
    this.state = {
    id: '',
    name: '',
    provider: '',
    }
    }
    // Google Login
    responseGoogle = (res) => {
    this.setState({
    id: res.googleId,
    name: res.profileObj.name,
    provider: 'google'
    });
    this.doSignUp();
    }
    // Kakao Login
    responseKakao = (res) => {
    this.setState({
    id: res.profile.id,
    name: res.profile.properties.nickname,
    provider: 'kakao'
    });
    this.doSignUp();
    }

    // Login Fail
    responseFail = (err) => {
    console.error(err);
    }
    doSignUp = () => {
        const { id, name, provider } = this.state;

    window.sessionStorage.setItem('id', id);
    window.sessionStorage.setItem('name', name);
    window.sessionStorage.setItem('provider', provider);
    this.props.onLogin();
    this.props.history.push('/');
    }

    render() {
    return (
    <Container>
    <GoogleLogin
    clientId={process.env.REACT_APP_Google}
    buttonText="Google"
    onSuccess={this.responseGoogle}
    onFailure={this.responseFail}
    />
    <KakaoButton
    jsKey={process.env.REACT_APP_Kakao}
    buttonText="Kakao"
    onSuccess={this.responseKakao}
    onFailure={this.responseFail}
    getProfile="true"
    />
    </Container>
    );
    }
    }

    const Container = styled.div`
    display: flex;
    flex-flow: column wrap;
    `

    const KakaoButton = styled(KakaoLogin)`
    padding: 0;
    width: 190px;
    height: 44px;
    line-height: 44px;
    color: #783c00;
    background-color: #FFEB00;
    border: 1px solid transparent;
    border-radius: 3px;
    font-size: 16px;
    font-weight: bold;
    text-align: center;
    `

    export default withRouter(Login);


    2) src/App.js

    - componentDidMount함수에서 세션스토리지에 id가 있는 경우 onLogin함수를 실행하고 없을 경우에는 onLogout함수를 실행하여 로그인을 유지함.

    - 또한 로그아웃 시, 소셜로그인으로 부터 전달받은 토큰을 제거하고 세션스토리지에 저장된 정보를 모두 삭제한다.

    import React, { Component } from 'react';
    import styled from 'styled-components';
    import Header from './Layout/Header';
    import Navigation from './Layout/Navigation';
    import Router from './Routes/Router';
    import Store from './Store/store';

    class App extends Component {

    constructor(props) {
    super(props)
    this.state = {
    logged: false,
    onLogin: this.onLogin,
    onLogout: this.onLogout
    }
    }

    // Login Func
    onLogin = () => {
    this.setState({
    logged: true
    });
    }

    // Logout Func
    onLogout = () => {
    this.setState({
    logged: false
    });

    const provider = window.sessionStorage.getItem('provider');
    //Google AccessToken Remove
    if(provider === 'google') {
    const auth2 = window.gapi.auth2.getAuthInstance();
    auth2.signOut().then(function() {
    console.log('Goolge Logout.');
    });
    }
    // Kakao AccessToken Remove
    else if(provider === 'kakao'){
    window.Kakao.Auth.logout(function() {
    console.log("Kakao logout");
    });
    }
    //SessionStorage Clear
    window.sessionStorage.clear();
    }

    componentDidMount() {
    const id = window.sessionStorage.getItem('id');
    if(id) {
    this.onLogin();
    }
    else {
    this.onLogout();
    }
    }

    render() {
    const { logged, onLogout } = this.state;

    return (
    <Store.Provider value={this.state}>
    <Layout>
    <Header logged={logged} onLogout={onLogout}/>
    <Navigation />
    <Content>
    <Router />
    </Content>
    </Layout>
    </Store.Provider>
    );
    }
    }

    const Layout = styled.div`
    margin: 0 auto;
    display: flex;
    width: 100%;
    flex-flow: row wrap;
    `
    const Content = styled.div`
    margin: 0 auto;
    `

    export default App;


    '2018~2019 > React.js' 카테고리의 다른 글

    now2.0  (0) 2018.12.21
    React로 블로그 만들기 #9  (2) 2018.11.05
    React로 블로그 만들기 #7  (0) 2018.11.01
    React로 블로그 만들기 #6  (5) 2018.10.30
    React로 블로그 만들기 #5  (3) 2018.10.29
Designed by Tistory.