일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- 객체지향프로그래밍
- 각자리수
- jsx
- 제곱함수
- math.pow
- SUPER
- 함수표현식
- 페어프로그래밍
- 수도코드
- render
- falsy
- JavaScript
- State
- 자료구조
- pseudocode
- ES6
- stack
- ReactDOM
- 깃헙
- github
- pair
- CLONE
- props
- Til
- 함수선언식
- while
- 스택
- react
- javascirpt
- reduce
Archives
- Today
- Total
강백호같은개발자
구글 로그인 본문
클라이언트 - 회원가입
// signup.js
/* eslint-disable react/prop-types */
/* eslint-disable no-unused-vars */
import React from "react";
import { withRouter, Link, useHistory } from "react-router-dom";
import axios from "axios";
axios.defaults.withCredentials = true;
class Signup extends React.Component {
constructor(props) {
super(props);
this.state = {
email: '',
password: '',
username: '',
mobile: ''
};
this.handleInputValue = this.handleInputValue.bind(this);
}
handleInputValue = key => e => {
this.setState({ [key]: e.target.value });
};
handleOnConfirmPasswordInput(confirmPasswordInput) {
this.setState({ confirmPassword: confirmPasswordInput });
}
doesPasswordMatch() {
const { password, confirmPassword } = this.state;
return password === confirmPassword;
}
confirmPasswordClassName() {
const { confirmPassword } = this.state;
if (confirmPassword) {
return this.doesPasswordMatch() ? 'is-valid' : 'is-invalid';
}
}
renderFeedbackMessage() {
const { confirmPassword } = this.state;
if (confirmPassword) {
if (!this.doesPasswordMatch()) {
return (
<div className="invalid-feedback">The password does not match</div>
);
}
}
}
render() {
const { email, password, mobile, username } = this.state;
return (
<div>
<center className="loginBox">
<h1>Sign Up</h1>
<form
onSubmit={e => {
e.preventDefault();
axios
.post('/user/signup', this.state)
.then(res => {
if (res.status === 409) {
alert('계정이 이미 존재합니다')
this.props.history.push('/')
}
else if (res.status === 200) {
alert('가 입이 완료되었습니다^^')
this.props.history.push('/login')
}
})
.catch(err =>
console.log(err)
);
}}
>
<link href="https://fonts.googleapis.com/css2?family=Courgette&family=Gloria+Hallelujah&display=swap" rel="stylesheet"></link>
<div>
<input className="inputForm"
placeholder="User Name"
onChange={this.handleInputValue('username')}
>
</input>
</div>
<div>
<input className="inputForm" type="email"
placeholder="Email"
onChange={this.handleInputValue('email')}>
</input>
</div>
<div>
<input className="inputForm"
type="password"
placeholder="Password"
onChange={this.handleInputValue('password')}>
</input>
</div>
<div >
<input
type="password"
className="inputForm"
id="confirmPasswordInput"
placeholder="Password Confirm"
onChange={e =>
this.handleOnConfirmPasswordInput(e.target.value)
}
/>
{this.renderFeedbackMessage()}
</div>
<button className="signupBtn" type="submit">
Signup
</button>
</form>
</center>
</div >
);
}
}
export default withRouter(Signup);
클라이언트 - 로그인
// login.js
/* eslint-disable react/prop-types */
import React from "react";
import { withRouter } from "react-router-dom";
import axios from "axios";
import Facebook from "./Facebook";
axios.defaults.withCredentials = true;
class Login extends React.Component {
constructor(props) {
super(props);
this.state = {
email: '',
password: ''
};
this.handleInputValue = this.handleInputValue.bind(this);
}
handleInputValue = key => e => {
this.setState({ [key]: e.target.value });
};
render() {
const { email, password } = this.state;
const { handleIsLoginChange } = this.props;
return (
<div className="loginBack">
<center className="loginBox" >
<link href="https://fonts.googleapis.com/css2?family=Courgette&display=swap" rel="stylesheet"></link>
<h1>Login</h1>
<form
onSubmit={e => {
e.preventDefault();
return axios
.post('/user/login', {
email: email,
password: password
})
.then((res) => {
localStorage.setItem('user', JSON.stringify(res.data.token));
handleIsLoginChange();
this.props.history.push('/mypage');
})
.catch(err => console.log(err));
}}
>
<div>
<input className="inputForm"
type="email"
placeholder="Eamil"
onChange={this.handleInputValue('email')}>
</input>
</div>
<div>
<input className="inputForm"
type="password"
placeholder="Password"
onChange={this.handleInputValue('password')}>
</input>
</div>
<div>
<button className="loginBtn" type="submit">
Login
</button>
</div>
<div id="snsLogin">
<span className="fbLogin">
<Facebook />
</span>
{/* 밑의 구글로그인 부분은 a태그로 무조건 감싸져야 합니다. -현진- */}
<a href="http://3.34.193.46.xip.io:5000/auth/google" className="googleBtn">
<img src="https://img.icons8.com/color/48/000000/google-logo.png" />Google with Login</a>
</div>
</form>
</center>
</div>
);
}
}
export default withRouter(Login);
백엔드-passport/
// google.js
const passport = require('passport');
const GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;
const { User } = require('../models');
module.exports = () => {
console.log('여기');
passport.use(new GoogleStrategy({
clientID: process.env.GOOGLE_ID,
clientSecret: process.env.GOOGLE_SECRET,
callbackURL: '/auth/google/callback',
}, async (accessToken, refreshToken, profile, done) => {
console.log('kakao profile', profile);
try {
const exUser = await User.findOne({
where: { email: profile._json.email, provider: 'google' },
});
if (exUser) {
done(null, exUser);
} else {
console.log(profile._json.email,'=============')
const newUser = await User.create({
email: profile._json && profile._json.email,
snsId: profile.id,
provider: 'google',
username: profile._json.name,
});
done(null, newUser);
}
} catch (error) {
console.error(error);
done(error);
}
}));
};
// index.js
const passport = require('passport');
const google = require('./google');
const { User } = require('../models');
module.exports = () => {
passport.serializeUser((user, done) => { // 서버쪽에 [{ id: 1, cookie: 'clhxy' }]
done(null, user.id);
});
passport.deserializeUser(async (id, done) => {
try {
const user = await User.findOne({ where: { id }});
done(null, user); // req.user
} catch (error) {
console.error(error);
done(error);
}
});
google();
};
백엔드 - routes/auth.js
// auth.js
const express = require('express');
const router = express.Router();
const passport = require('passport');
router.get('/google',
passport.authenticate('google', { scope: ['https://www.googleapis.com/auth/plus.login', 'email'], prompt: 'select_account' }));
router.get('/google/callback', (req, res, next) => {
passport.authenticate('google', (authError, user,) => {
req.session.userid = user.dataValues.email
res.cookie('user', user.dataValues.username);
res.redirect(`http://localhost:3000?data=${user.dataValues.email}`);
req.login(user,(err) => {
if(err) {
res.status(404).send('구글로그인 에러');
}
})
})(req, res, next)
})
module.exports = router;
백엔드 - package.json
{
"name": "k-food-dictionary-server",
"version": "1.0.0",
"description": "<a href=\"https://gitmoji.carloscuesta.me\"> <img src=\"https://img.shields.io/badge/gitmoji-%20😜%20😍-FFDD67.svg?style=flat-square\" alt=\"Gitmoji?style=flat-square&logo=appveyor\"> </a> <a href=\"https://github.com/codestates/Saekgalpi-ColorPalette\"><img src =\"https://img.shields.io/badge/github-kFood-lightgrey?style=flat-square&logo=appveyor\"></a> <img src=\"https://img.shields.io/badge/npm-v6.14.4-important?style=flat-square&logo=appveyor\"> <img src=\"https://img.shields.io/badge/node.js-v12.16.11-important?style=flat-square&logo=appveyor\">",
"main": "index.js",
"scripts": {
"dev": "nodemon app.js",
"hjtest": "nodemon mytest.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/wmc15156/K-Food-Dictionary-server.git"
},
"author": "kfood",
"license": "ISC",
"bugs": {
"url": "https://github.com/wmc15156/K-Food-Dictionary-server/issues"
},
"homepage": "https://github.com/wmc15156/K-Food-Dictionary-server#readme",
"dependencies": {
"aws-sdk": "^2.734.0",
"connect-redis": "^5.0.0",
"cookie-parser": "^1.4.5",
"cors": "^2.8.5",
"crypto-js": "^4.0.0",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"express-session": "^1.17.1",
"jsonwebtoken": "^8.5.1",
"morgan": "^1.10.0",
"multer": "^1.4.2",
"multer-s3": "^2.9.0",
"mysql2": "^2.1.0",
"node-localStorage": "0.0.1",
"passport": "^0.4.1", //<===
"passport-google-oauth": "^2.0.0", // <=== 구글 OAUTH
"passport-kakao": "^1.0.0",
"redis": "^3.0.2",
"sequelize": "^6.3.4",
"utf8": "^3.0.0"
},
"devDependencies": {
"babel-eslint": "^10.1.0",
"eslint": "^7.6.0",
"eslint-config-airbnb": "^18.2.0",
"eslint-plugin-import": "^2.22.0",
"eslint-plugin-jsx-a11y": "^6.3.1",
"eslint-plugin-react": "^7.20.5",
"nodemon": "^2.0.4",
"sequelize-cli": "^6.2.0"
}
}