Skip to content
This repository has been archived by the owner on Aug 22, 2019. It is now read-only.

Verifying Badges for Display

Sue Smith edited this page Jul 10, 2014 · 12 revisions

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

Contents

Badge Types

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.

Verifying Hosted Badges

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.

Verifying Signed Badges

coming soon

Checking Badge Structure

coming soon

Checking Earner Email Addresses

coming soon

Clone this wiki locally