通过Go引用Laravel的会话

这篇文章是 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名が入る")
    ...
}

在config/session.php中的Cookie名字。

'cookie' => env(
    'SESSION_COOKIE',
    Str::slug(env('APP_NAME', 'laravel'), '_').'_session'
),

在这里设置。Cookie将以APP_NAME + _session的名称发行。

获取会话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])
    }
}

希望这篇文章能对某个人有所启发,即使不清楚具体需要在哪里。

广告
将在 10 秒后关闭
bannerAds