oauth
36786 ワード
github oauth
ログインボタンをクリックしてハブ に入ります.認証 認証が完了すると、認証コード付きコールバックURL にリダイレクトする. App.jsで構成部品をレンダリングするたびにurlにコードパラメータがあるかどうかを確認する場合は、認証コードをサーバに送信し、サーバからトークンへのアクセスを要求します.
(クライアントから直接OAuthアプリケーションにアクセストークンを要求するセキュリティが劣るため、サーバが要求することが望ましい) .
クライアント
App.js
callback.js
ログインボタン
(クライアントから直接OAuthアプリケーションにアクセストークンを要求するセキュリティが劣るため、サーバが要求することが望ましい)
クライアント
App.js
import React, { Component } from "react";
import { BrowserRouter as Router } from "react-router-dom";
import Login from "./components/Login";
import Mypage from "./components/Mypage";
import axios from "axios";
class App extends Component{
constructor(){
super();
this.state = {
isLogin: false,
accessToken:"",
};
this.getAccessToken = this.getAccessToken.bind(this);
}
async getAccessToken(authorizationCode){
await axios({
url:"https://localhost:8080/callback",
method:"post",
data: {
authorizationCode,
},
})
.then((res) => {
this.setState({isLogin: true, accessToken: res.data.accessToken})
})
.catch((err)=>{
console.log(err);
})
}
componentDidMount(){
const url = new URL(window.location.href);
const authorizationCode = url.searchParams.get("code");
if(authorizationCode){
this.getAccessToken(authorizationCode);
}
}
render(){
const {isLogin, accessToken} = this.state;
return(
<Router>
<div className="App">
{isLogin? <Mypage accessToken={accessToken} /> : <Login />}
</div>
</Router>
)
}
}
export default App;
Login.jsimport React, {Component} from "react";
class Login extends Component {
constructor(props){
super(props);
this.socialLoginHandler = this.socialLoginHandler.bind(this);
this.GITHUB_LOGIN_URL = "https://github.com/login/oauth/authorization?client_id="클라이언트 아이디";
socialLoginHandler(){
window.location.assign(this.GITHUB_LOGIN_URL);
}
render(){
return(
<div className="loginContainer">
OAuth 2.0으로 소셜 로그인을 구현해보세요.
<img id="logo" alt="logo" src="https://image.flaticon.com/icons/png/512/25/25231.png" />
<button onClick={this.socialLoginHandler} className="socialloginBtn">
</button>
</div>
);
}
}
export default Login;
Mypage.jsimport React, { Component } from "react";
import axios from "axios";
class Mypage extends Component {
constructor(props){
super(props);
this.state = {
images:[],
name:"",
login:"",
html_url:"",
public_repos:0,
}
}
async getGitHubUserInfo(){
let response = axios({
url: "https://apli.github.com/user",
method: "get",
headers: {
authorization: `token ${this.props.accessToken}`,
},
});
const {name, login, html_url, public_repos} = response.data;
this.setState({
name,
login,
html_url,
public_repos
});
}
async getImages(){
const {accessToken} = this.props;
let response = await axios({
url: "http://localhost:8080/images",
method:"get",
headers: {
authorization: `token ${accessToken}`,
}
});
const {images} = reponse.data;
this.setState({
images
})
}
componentDidMount(){
this.getGitHubUserInfo();
this.getImages();
}
render(){
const {accessToken} = this.props;
if(!accessToken){
return <div>로그인이 필요합니다</div>
}
const {name, login, html_url, public_repos, images} = this.state;
return (
<div>
<div className="mypageContainer">
<h3>Mypage</h3>
<hr />
<div>안녕하세요. <span className="name" id="name">{name}</span>님! Github 로그인이 완료되었습니다</div>
<div>
<div className="itme">나의 로그인 아이디:<span id="login">{login}</span></div>
<div className="item">나의 GitHub 주소:
<span id="html_url">{html_url}</span></div>
<div className="item">
나의 public 레포지토리 개수:
<span id="public_repos">{public_repos}</span>개
</div>
</div>
<div id="images">
{
images.map(img => <img key={img.file} src={img.blob} />)
}
</div>
</div>
</div >
);
}
export default Mypage;
サーバーcallback.js
require('dotenv').config();
const clientID = process.env.GITHUB_CLIENT_ID;
const clientSecret = process.env.GITHUB_CLIENT_SECRET;
const axios = require('axios');
module.exports = (req, res) => {
//req의 body로 authorization code가 들어온다.
console.log(req.body);
//이제 authorization code를 이용해 access token을 발급받기 위한 post 요청을 보낸다.
//https://docs.github.com/en/free-pro-team@latest/developers/apps/identifying-and-authorizing-users-for-github-apps#2-users-are-redirected-back-to-your-site-by-github
axios({
method: 'post',
url: `https://github.com/login/oauth/access_token`,
headers: {
accept: 'application/json',
},
data: {
client_id: clientID,
client_secret: clientSecret,
code: req.body.authorizationCode
}
}).then((response) => {
accessToken = response.data.access_token;
res.status(200).json({ accessToken: accessToken })
}).catch(e => {
res.status(404)
})
}
images.jsconst images = require('../resources/resources');
module.exports = (req, res) => {
//Mypage로부터 access token을 제대로 받아온 것이 맞다면, resource server의 images를 클라이언트로 보낸다
if (!req.headers.authorization) {
res.status(403).send({
message: 'no permission to access resources'
})
return;
}
res.status(200).send({ images })
}
Reference
この問題について(oauth), 我々は、より多くの情報をここで見つけました https://velog.io/@kaitlin_k/oauthテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol