A pluggable framework for managing user sessions in a Swift server using Kitura.
The latest version of Kitura-Session requires Swift 4.0 or later. You can download this version of the Swift binaries by following this link. Compatibility with other Swift versions is not guaranteed.
Add the Kitura-Session
package to the dependencies within your application’s Package.swift
file. Substitute "x.x.x"
with the latest Kitura-Session
release.
.package(url: "https://github.com/IBM-Swift/Kitura-Session.git", from: "x.x.x")
Add KituraSession
to your target's dependencies:
.target(name: "example", dependencies: ["KituraSession"]),
import KituraSession
In order to use the Session middleware on a Raw route, an instance of Session
has to be created:
public init(secret: String, cookie: [CookieParameter]?=nil, store: Store?=nil)
Where:
- secret is a String to be used for session encoding. It should be a large unguessable string, a minimum of 14 characters long.
- cookie is a list of options for session's cookies. The options are (as specified in the
CookieParameter
enumeration):name
- cookie's name, defaults to "kitura-session-id".path
- cookie's path attribute, this defines the path for which this cookie should be supplied. Defaults to "/" which means allow any path.secure
- cookie's secure attribute, this indicates whwether the cookie should be provided only over secure (https) connections. Defaults to false.maxAge
- cookie's maxAge attribute, that is, the maximum age (in seconds) from the time of issue that the cookie should be kept for. Defaults to -1.0, i.e. no expiration.
- store is an instance of a plugin for a session backing store that implements the
Store
protocol. If not set,InMemoryStore
is used.
The cookie and store parameters are optional.
The secret parameter is used to secure the session ID and ensure that the session ID cannot be guessed. Secret is used to derive a pair of encryption and signature keys via PBKDF2 and a fixed IV to make the session ID cookie be authenticated and encrypted. Secret isn't used directly to encrypt or compute the MAC of the cookie.
In this example, an instance of RedisStore
is created that will be used to persist session data (see KituraSessionRedis
for more information). An instance of Session
is then created, specifying redisStore as the session store. Finally, the session instance is registered as a middleware on the desired path.
import Kitura
import KituraSession
import KituraSessionRedis
let redisStore = RedisStore(redisHost: host, redisPort: port)
let session = Session(secret: "Some secret", store: redisStore)
router.all(middleware: session)
Within your Kitura routes, you can store Any
type inside the request.session
for a given key. This can then be retrieved as an Any
and cast to the required type:
router.post("/session") {request, response, next in
request.session?["key"] = "value"
next()
}
router.get("/session") {request, response, next in
let value = request.session?["key"] as? String
next()
}
This Any
type must be JSON serializable, otherwise the session will fail when it attempts to save the session.
Available from Swift 4.1 or later
Within your Kitura routes, you can also store Codable
objects inside the request.session
for a given key. This can then be retrieved as the declared type:
public struct User: Codable {
let name: String
}
router.post("/user") { request, response, next in
let user = User(name: "Kitura")
request.session?["User"] = user
next()
}
router.get("/user") { request, response, next in
let user: User? = request.session?["Kitura"]
next()
}
To use sessions on a Codable route, declare a type that conforms to the TypeSafeSession protocol:
// Defines the session instance data
final class MySession: TypeSafeSession {
let sessionId: String // Requirement: every session must have an ID
var books: [Book] // User-defined type, where Book conforms to Codable
init(sessionId: String) { // Requirement: must be able to create a new (empty)
self.sessionId = sessionId // session containing just an ID. Assign a default or
books = [] // empty value for any non-optional properties.
}
}
// Defines the configuration of the user's type: how the cookie is constructed, and how the session is persisted.
extension MySession {
static let sessionCookie: SessionCookie = SessionCookie(name: "MySession", secret: "Top Secret")
static var store: Store?
}
The MySession type can then be included in the application's Codable route handlers. For example:
struct Book: Codable {
let title: String
let author: String
}
router.get("/cart") { (session: MySession, respondWith: ([Book]?, RequestError?) -> Void) in
respondWith(session.books, nil)
}
router.post("/cart") { (session: MySession, book: Book, respondWith: (Book?, RequestError) -> Void) in
var session = session // Required when mutating a Struct
session.books.append(book)
session.save()
respondWith(book, nil)
}
- Redis store
- SQL store using Kuery (community authored)
For more information visit our API reference.
We love to talk server-side Swift, and Kitura. Join our Slack to meet the team!
This library is licensed under Apache 2.0. Full license text is available in LICENSE.