ReactとGolangを連携して、認証機能をつけよう

前回は、Go言語で認証サーバーをつくりました。

今回はその続きとして、Reactでフロント側を実装し、サーバーと連携させます。

また、Auth0を使ってAPIのアクセス権限を設定します。


まずは、次のindex.htmlを書いて、必要なライブラリーを加えます。

views/index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>We R VR</title>
<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="http://cdn.auth0.com/js/auth0/8.5/auth0.min.js"></script>
<script type="text/javascript" src="static/js/auth0-variables.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
<script src="http://fb.me/react-0.14.7.js"></script>
<script src="https://fb.me/react-dom-0.14.7.js"></script>
<script type="text/babel" src="static/js/app.jsx"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container" id="app">
</div>
</body>
</html>

次に、auth0-variables.jsを作って、環境変数にauth0でつくられるAPIの認証情報をいれていきます。

static/js/auth0-variables.js

var AUTH0_CLIENT_ID='クライアントID';
var AUTH0_DOMAIN='ドメイン.auth0.com/';
var AUTH0_CALLBACK_URL=location.href;
var AUTH0_API_AUDIENCE='http://localhost:3000/products';

また、Reactで作られる各UI(コンポーネント)は、こちらにコードがあります。


では、実際にサーバー側に(main.goファイル)に、認証機能をつけいていきます。

パッケージは、”github.com/auth0-community/auth0"、jose “gopkg.in/square/go-jose.v2”を新たに加えていきます。

main.go

func authMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
secret := []byte("your secret key")
secretProvider := auth0.NewKeyProvider(secret)
audience := "http://localhost:3000/products"
configuration := auth0.NewConfiguration(secretProvider, []string{audience}, "https://yourdomein.auth0.com/", jose.HS256)
validator := auth0.NewValidator(configuration)
token, err := validator.ValidateRequest(r)
if err != nil {
fmt.Println(err)
fmt.Println("token is not valid", token)
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte("unauthorized"))
} else {
next.ServeHTTP(w, r)
}
})
}

新しく、 authMiddleware 関数を入れることで、auth0からくるtokenの検証を行っています。この関数を/productsと/products/{slug}/feedbackエンドポイントに渡すことで、APIの認証機能を加えています。


サーバー側で認証機能はつけました。

次は、フロントサイド(React側の)実装について、みていきます。app.goファイルの最終的なコードはこちらになります。

var App = React.createClass({
componentWillMount: function() {
this.setupAjax();
this.parseHash();
this.setState();
},
setupAjax: function() {
$.ajaxSetup({
'beforeSend': function(xhr) {
if (localStorage.getItem('access_token')) {
xhr.setRequestHeader('Authorization',
'Bearer ' + localStorage.getItem('access_token'));
}
}
});
},
parseHash: function(){
this.auth0 = new auth0.WebAuth({
domain: AUTH0_DOMAIN,
clientID: AUTH0_CLIENT_ID
});
this.auth0.parseHash(window.location.hash, function(err, authResult) {
if (err) {
return console.log(err);
}
console.log(authResult);
if(authResult !== null && authResult.accessToken !== null && authResult.idToken !== null){
localStorage.setItem('access_token', authResult.accessToken);
localStorage.setItem('id_token', authResult.idToken);
localStorage.setItem('profile', JSON.stringify(authResult.idTokenPayload));
}
});
},
setState: function(){
var idToken = localStorage.getItem('id_token');
if(idToken){
this.loggedIn = true;
} else {
this.loggedIn = false;
}
},
render: function() {
if (this.loggedIn) {
return (<LoggedIn />);
} else {
return (<Home />);
}
}
});

コンポーネントをrenderingする前に、setupAjax/parseHash/setState/の3つの関数をセットして、local側に認証tokenをもたせている処理になります。

以下のコンポーネント(Home/LoggedIn/Product)も似た処理になります。

以上で、今回のチュートリアルをおわります。

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.