|
1 | | -# Perfect-Authentication |
| 1 | +# Perfect Local Authentication (PostgreSQL) |
2 | 2 |
|
3 | 3 | [](http://perfect.org/get-involved.html) |
4 | 4 |
|
|
15 | 15 | [](https://gitter.im/PerfectlySoft/Perfect?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) |
16 | 16 | [](http://perfect.ly) [](https://badge.fury.io/gh/PerfectlySoft%2FPerfect-CURL) |
17 | 17 |
|
18 | | -## OAuth2 Library for Perfect |
| 18 | +## Perfect Local Authentication (PostgreSQL) Library |
19 | 19 |
|
20 | 20 |
|
21 | | -This project provides [OAuth2](https://oauth.net/2/) libraries and select OAuth2 provider drivers - Facebook, Google, GitHub. |
| 21 | +This package provides Local Authentication libraries for projects that require locally stored and handled authentication. |
22 | 22 |
|
23 | | -Full documentation can be found at [http://www.perfect.org/docs/OAuth2.html](http://www.perfect.org/docs/OAuth2.html) |
| 23 | +Full documentation can be found at [http://www.perfect.org/docs/authentication.html](http://www.perfect.org/docs/authentication.html.html) |
24 | 24 |
|
25 | | -A demo application can be found at [https://github.com/PerfectExamples/Perfect-Authentication-Demo](https://github.com/PerfectExamples/Perfect-Authentication-Demo) that shows the usage of the system. |
| 25 | +A template application can be found at [https://github.com/PerfectlySoft/Perfect-Local-Auth-PostgreSQL-Template](https://github.com/PerfectlySoft/Perfect-Local-Auth-PostgreSQL-Template), providing a fully functional starting point, as well as demonstrating the usage of the system. |
26 | 26 |
|
27 | 27 | This package builds with Swift Package Manager and is part of the [Perfect](https://github.com/PerfectlySoft/Perfect) project. It was written to be stand-alone and so does not require PerfectLib or any other components. |
28 | 28 |
|
29 | | -Ensure you have installed and activated the latest Swift 3.0 tool chain. |
| 29 | +Ensure you have installed and activated the latest Swift 3.x tool chain. |
30 | 30 |
|
31 | 31 | ## Adding to your project |
32 | 32 |
|
33 | 33 | Add this project as a dependency in your Package.swift file. |
34 | 34 |
|
35 | 35 | ``` swift |
36 | | -.Package(url: "https://github.com/PerfectlySoft/Perfect-Authentication.git", majorVersion: 1) |
| 36 | +.Package(url: "https://github.com/PerfectlySoft/Perfect-LocalAuthentication-PostgreSQL.git", majorVersion: 1) |
37 | 37 | ``` |
38 | 38 |
|
39 | | -To then use the OAuth2 module in your code: |
| 39 | +To then use the LocalAuthentication module in your code: |
40 | 40 |
|
41 | 41 | ``` swift |
42 | | -import OAuth2 |
| 42 | +import LocalAuthentication |
43 | 43 | ``` |
44 | 44 |
|
45 | 45 | ## Configuration |
46 | 46 |
|
47 | | -Each provider needs an "appid", also known as a "key", and a "secret". These are usually generated by the OAuth Host, such as Facebook, GitHub and Google developer consoles. These values, as well as an "endpointAfterAuth" and "redirectAfterAuth" value must be set for each provider you wish to use. |
| 47 | +It is important to configure the following in main.swift to set up database and session configuration: |
48 | 48 |
|
49 | | -To configure Facebook as a provider: |
| 49 | +Import the required modules: |
50 | 50 |
|
51 | 51 | ``` swift |
52 | | -FacebookConfig.appid = "yourAppID" |
53 | | -FacebookConfig.secret = "yourSecret" |
54 | | -FacebookConfig.endpointAfterAuth = "http://localhost:8181/auth/response/facebook" |
55 | | -FacebookConfig.redirectAfterAuth = "http://localhost:8181/" |
| 52 | +import PerfectSession |
| 53 | +import PerfectSessionPostgreSQL |
| 54 | +import PerfectCrypto |
| 55 | +import LocalAuthentication |
56 | 56 | ``` |
57 | 57 |
|
58 | | -To configure Google as a provider: |
| 58 | +Initialize PerfectCrypto: |
59 | 59 |
|
60 | 60 | ``` swift |
61 | | -GoogleConfig.appid = "yourAppID" |
62 | | -GoogleConfig.secret = "yourSecret" |
63 | | -GoogleConfig.endpointAfterAuth = "http://localhost:8181/auth/response/google" |
64 | | -GoogleConfig.redirectAfterAuth = "http://localhost:8181/" |
| 61 | +let _ = PerfectCrypto.isInitialized |
65 | 62 | ``` |
66 | 63 |
|
67 | | -To configure GitHub as a provider: |
| 64 | +Now set some defaults: |
68 | 65 |
|
69 | 66 | ``` swift |
70 | | -GitHubConfig.appid = "yourAppID" |
71 | | -GitHubConfig.secret = "yourSecret" |
72 | | -GitHubConfig.endpointAfterAuth = "http://localhost:8181/auth/response/github" |
73 | | -GitHubConfig.redirectAfterAuth = "http://localhost:8181/" |
| 67 | +// Used in email communications |
| 68 | +// The Base link to your system, such as http://www.example.com/ |
| 69 | +var baseURL = "" |
| 70 | + |
| 71 | +// Configuration of Session |
| 72 | +SessionConfig.name = "perfectSession" // <-- change |
| 73 | +SessionConfig.idle = 86400 |
| 74 | +SessionConfig.cookieDomain = "localhost" //<-- change |
| 75 | +SessionConfig.IPAddressLock = false |
| 76 | +SessionConfig.userAgentLock = false |
| 77 | +SessionConfig.CSRF.checkState = true |
| 78 | +SessionConfig.CORS.enabled = true |
| 79 | +SessionConfig.cookieSameSite = .lax |
74 | 80 | ``` |
75 | 81 |
|
76 | | -## Adding Routes |
| 82 | +Detailed Session configuration documentation can be dound at [https://www.perfect.org/docs/sessions.html](https://www.perfect.org/docs/sessions.html) |
77 | 83 |
|
78 | | -The OAuth2 system relies on an authentication / exchange system, which requires a URL to be specially assembled that the user is redirected to, and a URL that the user is returned to after the user has committed the authorization action. |
79 | | - |
80 | | -The first set of routes below are the action URL's that will redirect to the OAuth2 provider's system. They can be anything you wish them to be. The user will never see anything on them as they will be immediately redirected to the correct place. |
81 | | - |
82 | | -The second set of routes below are where the OAuth2 provider should return the user to. Note that this is the same as the "endpointAfterAuth" configuration option. Once the "authResponse" function has been completed the user is automatically forwarded to the URL in the "redirectAfterAuth" option. |
| 84 | +The database and email configurations should be set as follows (if using JSON file config): |
83 | 85 |
|
84 | 86 | ``` swift |
85 | | -var routes: [[String: Any]] = [[String: Any]]() |
| 87 | +let opts = initializeSchema("./config/ApplicationConfiguration.json") // <-- loads base config like db and email configuration |
| 88 | +httpPort = opts["httpPort"] as? Int ?? httpPort |
| 89 | +baseURL = opts["baseURL"] as? String ?? baseURL |
| 90 | +``` |
86 | 91 |
|
87 | | -routes.append(["method":"get", "uri":"/to/facebook", "handler":Facebook.sendToProvider]) |
88 | | -routes.append(["method":"get", "uri":"/to/github", "handler":GitHub.sendToProvider]) |
89 | | -routes.append(["method":"get", "uri":"/to/google", "handler":Google.sendToProvider]) |
| 92 | +Otherwise, these will need to be set equivalent to this function [https://github.com/PerfectlySoft/Perfect-LocalAuthentication-PostgreSQL/blob/master/Sources/LocalAuthentication/Schema/InitializeSchema.swift](https://github.com/PerfectlySoft/Perfect-LocalAuthentication-PostgreSQL/blob/master/Sources/LocalAuthentication/Schema/InitializeSchema.swift). |
90 | 93 |
|
91 | | -routes.append(["method":"get", "uri":"/auth/response/facebook", "handler":Facebook.authResponse]) |
92 | | -routes.append(["method":"get", "uri":"/auth/response/github", "handler":GitHub.authResponse]) |
93 | | -routes.append(["method":"get", "uri":"/auth/response/google", "handler":Google.authResponse]) |
94 | | -``` |
| 94 | +Set the session driver: |
95 | 95 |
|
96 | | -## Information returned and made available |
| 96 | +``` swift |
| 97 | +let sessionDriver = SessionPostgresDriver() |
| 98 | +``` |
97 | 99 |
|
98 | | -After the user has been authenticated, certain information is gleaned from the OAuth2 provider. |
| 100 | +### Request & Response Filters |
99 | 101 |
|
100 | | -Note that the session ID can be retrieved using: |
| 102 | +The following two session filters need to be added to your server config: |
101 | 103 |
|
102 | 104 | ``` swift |
103 | | -request.session?.token |
| 105 | +// (where filter is a [[String: Any]] object) |
| 106 | +filters.append(["type":"request","priority":"high","name":SessionPostgresFilter.filterAPIRequest]) |
| 107 | +filters.append(["type":"response","priority":"high","name":SessionPostgresFilter.filterAPIResponse]) |
104 | 108 | ``` |
105 | 109 |
|
106 | | -The user-specific information can be accessed as part of the session info: |
| 110 | +For example, see [https://github.com/PerfectlySoft/Perfect-Local-Auth-PostgreSQL-Template/blob/master/Sources/PerfectLocalAuthPostgreSQLTemplate/configuration/Filters.swift](https://github.com/PerfectlySoft/Perfect-Local-Auth-PostgreSQL-Template/blob/master/Sources/PerfectLocalAuthPostgreSQLTemplate/configuration/Filters.swift) |
107 | 111 |
|
108 | | -``` swift |
109 | | -// The UserID as defined by the provider |
110 | | -request.session?.userid |
| 112 | +### Add routes for login, register etc |
111 | 113 |
|
112 | | -// designates the OAuth2 source - useful if you are allowing multiple OAuth providers |
113 | | -request.session?.data["loginType"] |
| 114 | +The following routes can be added as needed or customized to add login, logout, register: |
114 | 115 |
|
115 | | -// The access token obtained in the process |
116 | | -request.session?.data["accessToken"] |
| 116 | +``` swift |
| 117 | +// Login |
| 118 | +routes.append(["method":"get", "uri":"/login", "handler":Handlers.login]) // simply a serving of the login GET |
| 119 | +routes.append(["method":"post", "uri":"/login", "handler":LocalAuthWebHandlers.login]) |
| 120 | +routes.append(["method":"get", "uri":"/logout", "handler":LocalAuthWebHandlers.logout]) |
| 121 | + |
| 122 | +// Register |
| 123 | +routes.append(["method":"get", "uri":"/register", "handler":LocalAuthWebHandlers.register]) |
| 124 | +routes.append(["method":"post", "uri":"/register", "handler":LocalAuthWebHandlers.registerPost]) |
| 125 | +routes.append(["method":"get", "uri":"/verifyAccount/{passvalidation}", "handler":LocalAuthWebHandlers.registerVerify]) |
| 126 | +routes.append(["method":"post", "uri":"/registrationCompletion", "handler":LocalAuthWebHandlers.registerCompletion]) |
| 127 | + |
| 128 | +// JSON |
| 129 | +routes.append(["method":"get", "uri":"/api/v1/session", "handler":LocalAuthJSONHandlers.session]) |
| 130 | +routes.append(["method":"get", "uri":"/api/v1/logout", "handler":LocalAuthJSONHandlers.logout]) |
| 131 | +routes.append(["method":"post", "uri":"/api/v1/register", "handler":LocalAuthJSONHandlers.register]) |
| 132 | +routes.append(["method":"login", "uri":"/api/v1/login", "handler":LocalAuthJSONHandlers.login]) |
| 133 | +``` |
117 | 134 |
|
118 | | -// The user's first name as supplied by the provider |
119 | | -request.session?.data["firstName"] |
| 135 | +An example can be found at [https://github.com/PerfectlySoft/Perfect-Local-Auth-PostgreSQL-Template/blob/master/Sources/PerfectLocalAuthPostgreSQLTemplate/configuration/Routes.swift](https://github.com/PerfectlySoft/Perfect-Local-Auth-PostgreSQL-Template/blob/master/Sources/PerfectLocalAuthPostgreSQLTemplate/configuration/Routes.swift) |
120 | 136 |
|
121 | | -// The user's last name as supplied by the provider |
122 | | -request.session?.data["lastName"] |
| 137 | +## Testing for authentication: |
123 | 138 |
|
124 | | -// The user's profile picture as supplied by the provider |
125 | | -request.session?.data["picture"] |
| 139 | +The user id can be accessed as follows: |
126 | 140 |
|
| 141 | +``` swift |
| 142 | +request.session?.userid ?? "" |
127 | 143 | ``` |
128 | 144 |
|
129 | | -With access to this information, you can now save to the database of your choice. |
| 145 | +If a user id (i.e. logged in state) is required to access a page, code such as this could be used to detect and redirect: |
130 | 146 |
|
| 147 | +``` swift |
| 148 | +let contextAuthenticated = !(request.session?.userid ?? "").isEmpty |
| 149 | +if !contextAuthenticated { response.redirect(path: "/login") } |
| 150 | +``` |
131 | 151 |
|
132 | 152 | ## Issues |
133 | 153 |
|
|
0 commit comments