Skip to content

Commit f28ee9b

Browse files
authored
Merge pull request #539 from sebj54/master
Add Firebase JWT example + docs for Firebase & Auth0
2 parents 5f2c523 + a07f2fe commit f28ee9b

File tree

4 files changed

+233
-5
lines changed

4 files changed

+233
-5
lines changed

README.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,53 @@ This example sends the signed claims:
650650

651651
NB: The JWT implementation only supports the RSA and HMAC based algorithms.
652652

653+
##### Configure and test JWT authentication with Auth0
654+
655+
First you need to create an account on [Auth0](https://auth0.com/auth/login).
656+
Once logged in, you have to create an application (its type does not matter). Collect the `Domain`
657+
and `Client ID` and keep them for a later use. Then, create an API: give it a name and fill the
658+
`identifier` field with your API endpoint's URL.
659+
660+
Then you have to configure the `jwtAuth.secret` configuration in your `api.php` file.
661+
Don't fill it with the `secret` you will find in your Auth0 application settings but with **a
662+
public certificate**. To find it, go to the settings of your application, then in "Extra settings".
663+
You will now find a "Certificates" tab where you will find your Public Key in the Signing
664+
Certificate field.
665+
666+
To test your integration, you can copy the [auth0/vanilla.html](examples/clients/auth0/vanilla.html)
667+
file. Be sure to fill these three variables:
668+
669+
- `authUrl` with your Auth0 domain
670+
- `clientId` with your Client ID
671+
- `audience` with the API URL you created in Auth0
672+
673+
⚠️ If you don't fill the audience parameter, it will not work because you won't get a valid JWT.
674+
675+
You can also change the `url` variable, used to test the API with authentication.
676+
677+
[More info](https://auth0.com/docs/api-auth/tutorials/verify-access-token)
678+
679+
##### Configure and test JWT authentication with Firebase
680+
681+
First you need to create a Firebase project on the [Firebase console](https://console.firebase.google.com/).
682+
Add a web application to this project and grab the code snippet for later use.
683+
684+
Then you have to configure the `jwtAuth.secret` configuration in your `api.php` file.
685+
Grab the public key via this [URL](https://www.googleapis.com/robot/v1/metadata/x509/[email protected]).
686+
There may be several certificates, just grab the one corresponding to your `kid` (if you don't
687+
know what it is, just test them all until you will be logged in).
688+
Now, just fill `jwtAuth.secret` with your public key.
689+
690+
To test your integration, you can copy the [firebase/vanilla.html](examples/clients/firebase/vanilla.html)
691+
file and the [firebase/vanilla-success.html](examples/clients/firebase/vanilla-success.html) file,
692+
used as a "success" page and to display the API result.
693+
694+
Replace, in both files, the Firebase configuration (`firebaseConfig` object).
695+
696+
You can also change the `url` variable, used to test the API with authentication.
697+
698+
[More info](https://firebase.google.com/docs/auth/admin/verify-id-tokens#verify_id_tokens_using_a_third-party_jwt_library)
699+
653700
## Authorizing operations
654701

655702
The Authorization model acts on "operations". The most important ones are listed here:

examples/clients/auth0/vanilla.html

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
<html>
22
<head>
3-
<meta charset="utf-8" />
3+
<meta charset="utf-8" />
44
<script>
55
var authUrl = 'https://php-crud-api.auth0.com/authorize'; // url of auth0 '/authorize' end-point
66
var clientId = ''; // client id as defined in auth0
7-
var audience = ''; // api audience as defined in auth0
8-
window.onload = function () {
7+
var audience = 'https://your-php-crud-api/api.php'; // api audience as defined in auth0
8+
var url = '/api.php/records/posts?join=categories&join=tags&join=comments&filter=id,eq,1';
9+
10+
function requestApi() {
911
var match = RegExp('[#&]access_token=([^&]*)').exec(window.location.hash);
1012
var accessToken = match && decodeURIComponent(match[1].replace(/\+/g, ' '));
1113
if (!accessToken) {
@@ -16,18 +18,32 @@
1618
req.onreadystatechange = function () {
1719
if (req.readyState==4) {
1820
console.log(req.responseText);
19-
document.getElementById('output').innerHTML = JSON.stringify(JSON.parse(req.responseText), undefined, 4);
21+
try {
22+
document.getElementById('output').innerHTML = JSON.stringify(JSON.parse(req.responseText), undefined, 4);
23+
} catch (error) {
24+
document.getElementById('output').innerHTML = req.responseText;
25+
}
2026
}
2127
}
22-
url = '/api.php/records/posts?join=categories&join=tags&join=comments&filter=id,eq,1';
2328
req.open("GET", url, true);
2429
req.setRequestHeader('X-Authorization', 'Bearer '+accessToken);
2530
req.send();
2631
}
2732
};
33+
34+
window.onload = function() {
35+
requestAPI()
36+
document.getElementById('request-btn').onclick = function(e) {
37+
e.preventDefault()
38+
requestAPI()
39+
}
40+
}
2841
</script>
2942
</head>
3043
<body>
44+
<p>
45+
<button type="button" id="request-btn">Request API</button>
46+
</p>
3147
<pre id="output"></pre>
3248
</body>
3349
</html>
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="UTF-8">
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
7+
<meta http-equiv="X-UA-Compatible" content="ie=edge">
8+
<title>Success</title>
9+
10+
<script src="https://www.gstatic.com/firebasejs/6.0.2/firebase-app.js"></script>
11+
<script src="https://www.gstatic.com/firebasejs/6.0.2/firebase-auth.js"></script>
12+
13+
<script>
14+
// Your web app's Firebase configuration
15+
var firebaseConfig = {
16+
apiKey: "",
17+
authDomain: "",
18+
databaseURL: "",
19+
projectId: "",
20+
storageBucket: "",
21+
messagingSenderId: "",
22+
appId: ""
23+
};
24+
// Initialize Firebase
25+
firebase.initializeApp(firebaseConfig);
26+
</script>
27+
28+
<script>
29+
var url = '/api.php/records/posts?join=categories&join=tags&join=comments&filter=id,eq,1';
30+
31+
function requestAPI(accessToken) {
32+
var req = new XMLHttpRequest();
33+
req.onreadystatechange = function () {
34+
if (req.readyState == 4) {
35+
try {
36+
document.getElementById('output').innerHTML = JSON.stringify(JSON.parse(req.responseText),
37+
undefined, 4);
38+
} catch (error) {
39+
document.getElementById('output').innerHTML = req.responseText;
40+
}
41+
}
42+
}
43+
req.open("GET", url, true);
44+
req.setRequestHeader('X-Authorization', 'Bearer ' + accessToken);
45+
req.send();
46+
}
47+
48+
function initApp() {
49+
firebase.auth().onAuthStateChanged(function (user) {
50+
if (user) {
51+
// User is signed in.
52+
var displayName = user.displayName;
53+
var email = user.email;
54+
var emailVerified = user.emailVerified;
55+
var photoURL = user.photoURL;
56+
var uid = user.uid;
57+
var phoneNumber = user.phoneNumber;
58+
var providerData = user.providerData;
59+
user.getIdToken().then(function (accessToken) {
60+
document.getElementById('sign-in-status').textContent = 'Signed in';
61+
document.getElementById('account-details').textContent = JSON.stringify({
62+
displayName: displayName,
63+
email: email,
64+
emailVerified: emailVerified,
65+
phoneNumber: phoneNumber,
66+
photoURL: photoURL,
67+
uid: uid,
68+
accessToken: accessToken,
69+
providerData: providerData
70+
}, undefined, 4);
71+
72+
requestAPI(accessToken)
73+
});
74+
} else {
75+
// User is signed out.
76+
document.getElementById('sign-in-status').textContent = 'Signed out';
77+
document.getElementById('account-details').textContent = 'null';
78+
}
79+
}, function (error) {
80+
console.log(error);
81+
});
82+
};
83+
84+
window.addEventListener('load', initApp);
85+
</script>
86+
</head>
87+
88+
<body>
89+
<h1>Firebase Login Success (or not)</h1>
90+
91+
<div id="sign-in-status"></div>
92+
<pre id="account-details"></pre>
93+
94+
<pre id="output"></pre>
95+
</body>
96+
97+
</html>
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<meta http-equiv="X-UA-Compatible" content="ie=edge">
7+
<title>
8+
Firebase
9+
</title>
10+
11+
<!-- The core Firebase JS SDK is always required and must be listed first -->
12+
<script src="https://www.gstatic.com/firebasejs/6.0.2/firebase-app.js"></script>
13+
<script src="https://www.gstatic.com/firebasejs/6.0.2/firebase-auth.js"></script>
14+
15+
<script>
16+
// Your web app's Firebase configuration
17+
var firebaseConfig = {
18+
apiKey: "",
19+
authDomain: "",
20+
databaseURL: "",
21+
projectId: "",
22+
storageBucket: "",
23+
messagingSenderId: "",
24+
appId: ""
25+
};
26+
// Initialize Firebase
27+
firebase.initializeApp(firebaseConfig);
28+
</script>
29+
30+
<script src="https://cdn.firebase.com/libs/firebaseui/4.0.0/firebaseui.js"></script>
31+
<link type="text/css" rel="stylesheet" href="https://cdn.firebase.com/libs/firebaseui/4.0.0/firebaseui.css" />
32+
33+
<script type="text/javascript">
34+
// FirebaseUI config.
35+
var uiConfig = {
36+
signInSuccessUrl: './vanilla-success.html',
37+
signInOptions: [
38+
// Leave the lines as is for the providers you want to offer your users.
39+
firebase.auth.GoogleAuthProvider.PROVIDER_ID,
40+
firebase.auth.FacebookAuthProvider.PROVIDER_ID,
41+
firebase.auth.TwitterAuthProvider.PROVIDER_ID,
42+
firebase.auth.GithubAuthProvider.PROVIDER_ID,
43+
firebase.auth.EmailAuthProvider.PROVIDER_ID,
44+
firebase.auth.PhoneAuthProvider.PROVIDER_ID,
45+
firebaseui.auth.AnonymousAuthProvider.PROVIDER_ID
46+
],
47+
// tosUrl and privacyPolicyUrl accept either url string or a callback
48+
// function.
49+
// Terms of service url/callback.
50+
tosUrl: '<your-tos-url>',
51+
// Privacy policy url/callback.
52+
privacyPolicyUrl: function() {
53+
window.location.assign('<your-privacy-policy-url>');
54+
}
55+
};
56+
57+
// Initialize the FirebaseUI Widget using Firebase.
58+
var ui = new firebaseui.auth.AuthUI(firebase.auth());
59+
// The start method will wait until the DOM is loaded.
60+
ui.start('#firebaseui-auth-container', uiConfig);
61+
</script>
62+
</head>
63+
<body>
64+
<h1>Firebase login</h1>
65+
66+
<div id="firebaseui-auth-container"></div>
67+
</body>
68+
</html>

0 commit comments

Comments
 (0)