/** * Copyright 2018 The Nakama Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ namespace Nakama { using System; using System.Text; using System.Collections.Generic; using TinyJson; /// public class Session : ISession { private static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); /// public string AuthToken { get; } /// public bool Created { get; } /// public long CreateTime { get; } /// public long ExpireTime { get; } /// public bool IsExpired => HasExpired(DateTime.UtcNow); /// public string Username { get; } /// public string UserId { get; } /// public bool HasExpired(DateTime dateTime) { var expireDatetime = Epoch + TimeSpan.FromSeconds(ExpireTime); return dateTime > expireDatetime; } private Session(string authToken, bool created) { var span = DateTime.UtcNow - Epoch; Created = created; CreateTime = span.Seconds; AuthToken = authToken; var json = JwtUnpack(authToken); var decoded = json.FromJson>(); ExpireTime = Convert.ToInt64(decoded["exp"]); Username = decoded["usn"].ToString(); UserId = decoded["uid"].ToString(); } public override string ToString() { return $"Session(Created={Created}, ExpireTime={ExpireTime}, IsExpired={IsExpired}, Username={Username}, UserId={UserId})"; } /// /// Restore a session from an authentication token. /// /// The authentication token from a Session. /// A session restored from the authentication token. public static ISession Restore(string authToken) { return Restore(authToken, false); } internal static ISession Restore(string authToken, bool created) { return new Session(authToken, created); } private static string JwtUnpack(string jwt) { // Hack decode JSON payload from JWT. var payload = jwt.Split('.')[1]; var padLength = Math.Ceiling(payload.Length / 4.0) * 4; payload = payload.PadRight(Convert.ToInt32(padLength), '=').Replace('-', '+').Replace('_', '/'); return Encoding.UTF8.GetString(Convert.FromBase64String(payload)); } } }