-
Notifications
You must be signed in to change notification settings - Fork 263
Verifying Badges for Display
If you plan on displaying earner badges within a site, application or widget, you are encouraged to verify the badges first. In this guide we will work through the recommended verification steps.
If you're new to badge displaying, see also:
You can use the Displayer API to retrieve badges from the earner's Mozilla Backpack. The badges you receive from the Backpack will be in groups (known as collections in the Backpack user interface). The earner can collect badges within these groups, deciding whether to make each group public or not. You will only be able to retrieve badges that a user has designated as public.
The public badge list that you retrieve from the Backpack will include an assertion for each badge awarded to the earner. In order to verify and display the badges, your application, site or widget code will naturally need to parse the included JSON data. Some familiarity with the structure of an assertion is therefore required.
To verify an earner badge, you need to:
- check that the badge assertion is structurally valid
- check the badge assertion's verification URL
- check that the badge has not been revoked - only for signed assertions
- verify the hashed earner identity - particularly if identity has been hashed
- carry out JWS verification using a public key - only for signed assertions
- Badge Types
- Verifying Hosted Badges
- Verifying Signed Badges
- Checking Badge Structure
- Checking Earner Email Addresses
Awarded badges can be either hosted or signed. With a hosted badge, the issuer hosts three JSON files representing:
- the badge assertion
- the badge class
- the issuer organization
The badge assertion includes a link to the badge class, which includes a link to the issuer organization. The issuer sends the URL of the badge assertion to the Backpack.
With a signed badge, the issuer sends the Backpack a JSON Web Signature representing the badge assertion - the badge class and issuer organization are still stored in hosted files.
The structure is discussed in more detail here: Assertion Information for the Uninitiated
When you request a badge group from the Displayer API, you will receive a response including an array of badges:
{
"userId": 12345,
"groupId": 67890,
"badges": [
{
"lastValidated": "2014-04-28T17:27:22.000Z",
"hostedUrl": "http://example.org/badge-assertion.json",
"assertion": {
"uid": "abcde12345",
"recipient": "sha256$abcde1345",
"badge": {
"name": "Badge Name",
"description": "Badge description.",
"image": "https://example.org/badge.png",
"criteria": "https://example.org/criteria",
"issuer": {
"name": "Issuer Name",
"url": "http://issuersite.org",
"_location": "http://example.org/issuer-organization.json",
"origin": "http://issuersite.org"
},
"_location": "http://issuersite.org/badge-class.json"
},
"verify": {
"url": "http://example.org/badge-assertion.json",
"type": "hosted"
},
"issuedOn": 1398705955,
"_originalRecipient": {
"identity": "sha256$abcde1345",
"type": "email",
"hashed": true
},
"issued_on": 1398705955
},
"imageUrl": "https://backpack.openbadges.org/images/badge/abcde12345.png"
},
...
]
}
In order to verify a badge before displaying it, you will need to establish whether it is signed or hosted, as the verification process is different.
You can access this information in the assertion.verify.type
field within each badge in the array. In a node.js app the process may look something like this:
var express = require("express");
var logfmt = require("logfmt");
var app = express();
var http = require("http");
app.use(logfmt.requestLogger());
app.get('/', function(req, res) {
var earnerId = 12345;//from convert service
var groupId = 67890;//from earner groups request
var requestOptions = {
host : 'backpack.openbadges.org',
path : '/displayer/'+earnerId+'/group/'+groupId,
method : 'GET'
};
var displayRequest = http.request(requestOptions, function(reqResponse) {
var response = [];
reqResponse.setEncoding('utf8');
reqResponse.on('data', function (responseData) {
response.push(responseData);
});
reqResponse.on('end', function(){
var recData=JSON.parse(response.join(''));
console.log('response: ' + recData);
//get the 'badges' array
var badges = recData.badges;
for(var b=0; b<badges.length; b++){
var badge=badges[b];
//get the type for this assertion
var type = badge.assertion.verify.type;
if(type==='hosted'){
//verify as hosted
}
else if(type==='signed'){
//verify as signed
}
}
res.send('badges!');
});
});
displayRequest.on('error', function(e) {
console.error(e);
});
displayRequest.end();
});
In the conditional blocks inside the loop through the badges, you could then carry out verification tailored to whether each badge is signed or hosted.
For a hosted badge, the verification process requires checking that the assertion.verify.url
resource is available, checking structural validity and checking the earner email address.
To verify that the badge assertion is available, meaning that the JSON file representing the awarded badge is available online at the specified URL, displayers should perform a GET
request on the location listed in the badge data assertion.verify.url
field.
In a node.js app, it might look something like this simplified excerpt:
var checkOptions = {
method: 'GET',
host: 'example.org',
path: '/badge-assertion.json'
};
var checkReq = http.request(checkOptions, function(checkResponse) {
var status = checkResponse.statusCode;
if(status===200)
//status is ok
else
//status is not ok
});
If the location listed in the assertion.verify.url
field does not eventually return a 200 OK
status, the assertion should be considered invalid.
If the URL does return a 200 OK
status, displayers can proceed to check the badge structure and check the email address.
coming soon
coming soon
coming soon