この記事は Laravel Advent Calendar 2019 #2 12/7の記事です。
枠が空いてたので前日に入れてしまいました。kubotakです。宜しくおねがいします。
前置き
LaravelよりGoな記事です。Laravelerの皆さんすみません。
今回はLaravelでAuth認証を行ったユーザーセッションをGoのアプリケーションから参照するぞ!という記事です。
また、Laravel側ではMemcachedにセッション情報を保持しているケースで説明します。
あとあと、実戦投入したわけではないのであらゆる責任は負いません。参考程度に見てもらえたらと思います。
このケースのニーズ
LaravelのいわゆるMPAからNextやNuxtのようなSSR機能のあるJavaScriptフレームワークに移行した(い)ケースで、バックエンドのAPIをGoに置き換えたいな、というマイノリティに刺さるかもしれません。
Next/NuxtからGoアプリケーションへの通信
みんな大好きAxiosで通信する想定で説明します。
まずユーザーがログインしているかどうかは、Laravelが発行するCookieで判断できますよね。
そのCookieをGoのAPI通信時もHTTP Headerにくっつけてあげましょう。
Axiosであればクライアントオプションに以下を追加することで通信にCookieが付属されます。
{
withCredentials: true
}
GoアプリケーションでCookieを取得
私はサクッとgithub.com/gorilla/mux
とnet/http
でREST APIを立てました。
ハンドラーで以下のようにリクエストからCookieが取得できます。
func Action(w http.ResponseWriter, r *http.Request) {
cookie, err := r.Cookie("ここにCookie名が入る")
...
}
Cookie名はconfig/session.php
の
'cookie' => env(
'SESSION_COOKIE',
Str::slug(env('APP_NAME', 'laravel'), '_').'_session'
),
ここで設定されますね。APP_NAME
+ _sessionという名前でCookieが発行されます。
セッションIDを取得する
Cookieが取得できたらセッションIDを取得したいですね。
ネットをさまよったらまさにというライブラリがありました。
github.com/chekun/golaravelsession
sid, err := golaravelsession.GetSessionID(cookie.Value, "LaravelのAPP_KEY")
これでセッションIDが取得できました。
ログインユーザーを特定する
続いてこのセッションIDからmemcachedのセッションデータを取得してユーザを特定したいですね。
Memcachedへの接続はこちらのライブラリを使いました。
github.com/rainycape/memcache
mc, err := memcache.New("127.0.0.1:11211")
ローカルのDockerに別途LaravelとMemcachedを立てたのでそちらのMemcachedに接続してます。
先程のセッションIDを利用してMemcachedからデータを取得したいと思います。
LaravelがMemcachedにセッション情報を書き込む際のキーは以下のようになってます。
APP_NAME + '_cache:' + sessionID
これに沿って
it, err := mc.Get("{APP_NAME}_cache:" + sid)
これでPHPシリアライズされたデータが取得できます。
先程のgithub.com/chekun/golaravelsession
を利用してシリアライズされたデータをデシリアライズします。
session, _ := golaravelsession.ParseSessionData(string(it.Value))
ログインセッションは以下のようなルールになっていて、これをキーとしてユーザーIDが格納されています。
login_ + guard名 + _ + 認証で使っているEloquentクラスのSHA-1
若干無理やりですが、以下のようにすることでログインしているユーザーのIDが取得できます。
for s := range session {
if regexp.MustCompile(`login_web_*`).Match([]byte(s.(string))) {
log.Print("LoginID: ", session[s])
}
}
どこに需要があるかわからない記事でしたが誰かの参考になれば幸いです。