dongyong1400
dongyong1400
2018-03-22 00:14

使用localStorage和Websocket自动授权

已采纳

I have a project I'm working on which is a single-page dynamic web app which uses Javascript and a Websocket to retrieve data from a Golang server. I've implemented the auto-authorization method described in this article. I was referred to that article from this one which at the end mentions to check out the first article I linked (just in case you were wondering what that first article was "improving" upon).

This is how my setup works:

  • Client loads app, and before anything dynamic loads, client connects to Websocket
  • Client sends login, device token, and session token through Websocket (of course if they were logged in before) from localStorage
  • Golang Websocket server checks if database has matching login, device token, session token, client's browser/version, etc (I get a few other pieces of data to match a device with the user's HTTP request for extra security)
  • If there's a match, Golang generates a new session token, updates the database match with it, and sends it back to the client
  • Client gets session token and updates it in their localStorage to use the next time they load the site

Now, don't get me wrong. Everything is working great... but there's one problem:

If a user logs in, then reloads the page a bunch of times as fast as they can, sometimes the websocket and server don't have enough time to get the user's next session token back to them. This of course causes their tokens to expire and be removed from the database and notifies the user that their credentials have either been expired or stolen (which really doesn't look good from a business standpoint).

I have some thoughts on solutions, but none seem promising in scalability and for the long run.

All thoughts and solutions on the matter are appreciated!

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

1条回答

  • dongle7882 dongle7882 3年前

    After login you should send two tokens to the browser, a short-lived session token (say, one hour) and a long-lived remember-me token (say, 30 days). The session token's TTL is reset to one hour every time the browser shows activity, but its value does not change.

    If and only if the session cookie has expired (or is otherwise invalid), the remember-me cookie is traded for a new, authenticated, session. This does not happen when reloading the page, only after the browser has been inactive for more than an hour.

    Prolonging the session happens purely on the server side. Only when trading the remember-me token is it critical that the browser receives and stores the new session token.

    You should not delete the remember-me token from the database immediately after first use. If I start my browser it restores previously open tabs, which may include multiple for your site. Consequently, your server will receive multiple requests (or websocket connections) almost simultaneously and those requests race for the new session-token.

    At my workplace we allow remember-me tokens to be used for up to two minutes after first use, and at most N times, whichever happens first. That fixes races and allows for retries in case of connectivity issues.

    点赞 评论 复制链接分享