Perfect Turnstile with SQLite 简体中文
This project integrates Stormpath's Turnstile authentication system into a single package with Perfect, and a SQLite ORM.
In your Package.swift file, include the following line inside the dependancy array:
.Package(
url: "https://github.com/PerfectlySoft/Perfect-Turnstile-SQLite.git",
majorVersion: 0, minor: 0
)
The framework includes certain basic routes:
POST /api/v1/login (with username & password form elements)
POST /api/v1/register (with username & password form elements)
GET /api/v1/logout
The following routes are available for browser testing:
http://localhost:8181
http://localhost:8181/login
http://localhost:8181/register
These routes are using Mustache files in the webroot directory.
Example Mustache files can be found in https://github.com/PerfectExamples/Perfect-Turnstile-SQLite-Demo
import PerfectLib
import PerfectHTTP
import PerfectHTTPServer
import SQLiteStORM
import PerfectTurnstileSQLite
// Used later in script for the Realm and how the user authenticates.
let pturnstile = TurnstilePerfectRealm()
// Set the connection variable
connect = SQLiteConnect("./authdb")
// Set up the Authentication table
let auth = AuthAccount(connect!)
auth.setup()
// Connect the AccessTokenStore
tokenStore = AccessTokenStore(connect!)
tokenStore?.setup()
// Create HTTP server.
let server = HTTPServer()
// Register routes and handlers
let authWebRoutes = makeWebAuthRoutes()
let authJSONRoutes = makeJSONAuthRoutes("/api/v1")
// Add the routes to the server.
server.addRoutes(authWebRoutes)
server.addRoutes(authJSONRoutes)
// Add more routes here
var routes = Routes()
// routes.add(method: .get, uri: "/api/v1/test", handler: AuthHandlersJSON.testHandler)
// Add the routes to the server.
server.addRoutes(routes)
// add routes to be checked for auth
var authenticationConfig = AuthenticationConfig()
authenticationConfig.include("/api/v1/check")
authenticationConfig.exclude("/api/v1/login")
authenticationConfig.exclude("/api/v1/register")
let authFilter = AuthFilter(authenticationConfig)
// Note that order matters when the filters are of the same priority level
server.setRequestFilters([pturnstile.requestFilter])
server.setResponseFilters([pturnstile.responseFilter])
server.setRequestFilters([(authFilter, .high)])
// Set a listen port of 8181
server.serverPort = 8181
// Where to serve static files from
server.documentRoot = "./webroot"
do {
// Launch the HTTP server.
try server.start()
} catch PerfectError.networkError(let err, let msg) {
print("Network error thrown: \(err) \(msg)")
}
Define the "Realm" - this is the Turnstile definition of how the authentication is handled. The implementation is specific to the SQLite datasource, although it is very similar between datasources and is designed to be generic and extendable.
let pturnstile = TurnstilePerfectRealm()
Define the location and name of the SQLite3 database:
connect = SQLiteConnect("./authdb")
Define, and initialize up the authentication table:
let auth = AuthAccount(connect!)
auth.setup()
Connect the AccessTokenStore:
tokenStore = AccessTokenStore(connect!)
tokenStore?.setup()
Create the HTTP Server:
let server = HTTPServer()
Register routes and handlers and add the routes to the server:
let authWebRoutes = makeWebAuthRoutes()
let authJSONRoutes = makeJSONAuthRoutes("/api/v1")
server.addRoutes(authWebRoutes)
server.addRoutes(authJSONRoutes)
Add routes to be checked for authentication:
var authenticationConfig = AuthenticationConfig()
authenticationConfig.include("/api/v1/check")
authenticationConfig.exclude("/api/v1/login")
authenticationConfig.exclude("/api/v1/register")
let authFilter = AuthFilter(authenticationConfig)
These routes can be either seperate, or as an array of strings. They describe inclusions and exclusions. In a forthcoming release wildcard routes will be supported.
Add request & response filters. Note the order which you specify filters that are of the same priority level:
server.setRequestFilters([pturnstile.requestFilter])
server.setResponseFilters([pturnstile.responseFilter])
server.setRequestFilters([(authFilter, .high)])
Now, set the port, static files location, and start the server:
// Set a listen port of 8181
server.serverPort = 8181
// Where to serve static files from
server.documentRoot = "./webroot"
do {
// Launch the HTTP server.
try server.start()
} catch PerfectError.networkError(let err, let msg) {
print("Network error thrown: \(err) \(msg)")
}