Provides JSON Web Token authentication for Zotonic API calls.
- Download and place this module in
your_zotonic_site/user/modules/
- Add the dependency jwt-erl to
~/.zotonic/your_zotonic_version/zotonic.config
:
{jwt, ".*", {git, "[email protected]:marianoguerra/jwt-erl.git", {branch, "master"}}}
- In the Zotonic root folder, run
make
to install the dependencies - Activate this module in Admin > System > Modules
Add to your site's config:
%%% JWT setting
{jwt_secret, "your-super-long-key-string"},
{jwt_expiration_offset, 24}
You can grab a good key from https://www.grc.com/passwords.htm
Note that this key should not change anymore.
The default expiration offset is 24 hours (expires 24 hours after creation).
If the app resides on a different server you need to enable Cross-Origin Resource Sharing:
%%% CORS settings
{service_api_cors, true},
{'Access-Control-Allow-Headers', "authorization, X-Requested-With, Content-Type"}
See also the Zotonic documentation on CORS.
This authentication method can only be trusted over a HTTPS connection, because regular HTTP traffic can be intercepted with a man-in-the-middle attack.
When a user signs in to the server, return a JWT token for next requests. For instance:
% Return a JWT token if successful
logon(Context) ->
Args = z_context:get_q_all(Context),
ContextAuth = controller_logon:logon(Args, [], Context),
User = z_acl:user(ContextAuth),
case User of
undefined -> {error, not_authenticated};
_ ->
Token = mod_service_auth_jwt:createToken(User, ContextAuth),
[Token]
end.
The token is typically returned through a service request.
When accessing a protected resource, pass the JWT token using the Bearer schema. The content of the header should look like:
Authorization: Bearer <token>
For instance:
xhr.setRequestHeader('Authorization', 'Bearer ' + token);
Note that XHR does not work with jsonp
.
When the token is valid:
- Access is granted to the protected resource (provided sufficient access rights)
- Response status 200 is be returned
In case of error (no token, expired or invalid token), a 401 status is returned, together with the reason.
In the Zotonic shell:
io_lib:format("~s", [mod_service_auth_jwt:createToken(1, Context)]).
Copy the token string.
In a new terminal window:
curl 'your_zotonic_site/api/base/info?id=1' -H 'Authorization : Bearer copied_token' -v
This should result in
...
< HTTP/1.1 200 OK
...
Possible responseText messages sent with a 401 error status:
no_jwt_received
jwt_empty
jwt_expired
jwt_error
no_valid_user
MIT