8
3

More than 3 years have passed since last update.

LaravelのセッションをGoから参照する

Last updated at Posted at 2019-12-06

この記事は 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/muxnet/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])
    }
}

どこに需要があるかわからない記事でしたが誰かの参考になれば幸いです。

8
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
3