1) Github > Settings > Developer Settings에서 Client Id와 Client secret key를 생성한다. Authorization callback URL
은 나의 웹 앱 URL을 적으면 된다.
2) 생성한 두 정보를 서버의 .env 파일에 저장한다.
1) Login.js (생략 예정)에서 Github API에 따라
https://github.com/login/oauth/authorize?client_id={내 Client Id}
에서 본인 인증 이후에 callback URL로 리디렉션되면서 autorization code를 받게된다. (이후 서버 callback 요청에 req.body
로 확인할 수 있다.
class App extends Component {
constructor() {
super();
this.state = {
isLogin: false,
accessToken: "",
};
this.getAccessToken = this.getAccessToken.bind(this);
}
// accessToken을 클라이언트 App.js내 state로 관리하고,
// getAcceessToken 메소드로 Github에서 넘겨받은 authorization code로 accessToken을 획득한다.
async getAccessToken(authorizationCode) {
await axios
.post('http://localhost:8080/callback',
{
authorizationCode
})
.then((data) => {
this.setState({
isLogin: true,
accessToken: data.data.accessToken
})
})
}
// componentDidMount는 랜더링 이후 즉시 호출되는 함수이다.
// 함수형 컴포넌트의 useEffect Hook과 비슷하다.
// 시점은 Login 랜더링 후, Mypage 랜더링 후가 되겠다.
componentDidMount() {
const url = new URL(window.location.href)
const authorizationCode = url.searchParams.get('code')
if (authorizationCode) {
this.getAccessToken(authorizationCode)
}
}
render() {} // ...생략
1) https://api.github.com/user 에서 사용자 정보를 받아올 것이다.
2) authorization 헤더에는 Login.js에서 받아온 authorization code를 사용해 획득한 accessToken을 넣어준다.
3) 여러 사용자 정보를 얻을 수 있다.
class Mypage extends Component {
constructor(props) {
super(props);
this.state = {
images: [],
name: "",
login: "",
html_url: "",
public_repos: null,
}
}
async getGitHubUserInfo() {
await axios
.get("https://api.github.com/user",
{
headers: {authorization: `token ${this.props.accessToken}`}
})
.then(data => {
const { name, login, html_url, public_repos } = data.data;
this.setState({
name,
login,
html_url,
public_repos
})
})
}
async getImages() {
await axios
.get(`http://localhost:8080/images`,
{
headers: {authorization: `token ${this.props.accessToken}`}
})
.then((data) => {
const { images } = data.data
this.setState({images})
})
}
1) https://github.com/login/oauth/access_token
의 Body에 client id, client secret, authorization code를 전달한다.
2) 전달받은 내용을 data.data에 접근하여 accessToken을 획득하여, 전달한다.
module.exports = async (req, res) => {
await axios
.post('https://github.com/login/oauth/access_token',
{
client_id: clientID,
client_secret: clientSecret,
code: req.body.authorizationCode
},
{
deaders: {Accept: 'application/json'}
})
.then((data) => {
const accessToken = data.data.access_token;
res.status(200).json({accessToken})
})
}
module.exports = async (req, res) => {
if (!req.headers.authorization) {
res.status(403).json({ message: "no permission to access resources" });
} else {
res.status(200).json({ images });
}
};