August 18, 2015

November 25, 2019

Google Cloud Endpoints, AngularJS and Json Web Tokens

In my private project I decided to use Google Endpoints (with Google App Engine) on backend side and AngularJS on frontend. For authorization I've chosen JWT (Json Web Tokens). At the beginning I wanted to use Google API Client library for JavaScript but I encountered two problems. At first, I can't set own authorization header. I can set token but it is insert in Authorization header which create a little issue. I found angular project for GAPI, angular-google-gapi, using this here is an example of adding token:

var BASE = '';
access_token: 'JWT TOKEN'
GApi.load('myapp', 'v1', BASE);

It adds token, even I can retrieve it on backend side and everything works correctly. But.. Google App Engine tries every time to use this token as Oauth2 token, logs:

D 12:38:44.375 Checking for id_token.
D 12:38:44.376 id_token verification failed: Unexpected encryption algorithm: u'HS256'
D 12:38:44.376 Checking for oauth token.
D 12:38:44.384 Oauth framework user didn't match oauth token user.

Second problem, why do I need an additional javascript library to making request to API? I didn't find a good reason to stay with GAPI because I want use my API. I decided to write my own directive.

"use strict"
var servicesModule = require("./_index.js")
* @ngInject
function MeetApiService($q, $http, AppSettings) {
var service = {}
var createEndpointUrl = function(endpoint, version) {
version = version || AppSettings.defaultApiVersion
endpoint = endpoint.replace(".", "/")
return [
service.get = function(endpoint, args, version) {
var deferred = $q.defer()
url: createEndpointUrl(endpoint, version),
method: "GET",
params: args,
.success(function(data) {
.error(function(err, status) {
deferred.reject(err, status)
return deferred.promise
} = function(endpoint, args, version) {
var deferred = $q.defer()
.post(createEndpointUrl(endpoint, version), args)
.success(function(data) {
.error(function(err, status) {
deferred.reject(err, status)
return deferred.promise
return service
servicesModule.service("MeetApiService", MeetApiService)

AppSettings contains projects settings like API url, default version for endpoints, project name, etc. Using this service I can easily make a request to Google Endpoints."users.login", {
password: vm.password,
function(response) {
// DONE!
function() {
MeetApiService.get("users.get", {}).then(function(response) {
// DONE!

What about authorization token? I'm using custom authorization field, something like:

$http.defaults.headers.common["X-MYPROJECT-Auth"] = "TOKEN"

It adds X-MYPROJECT-Auth header with TOKEN value to every request. Works perfectly! It has two advantages for me, it doesn't create mess in logs and it gives me the possibility to use Authorization field for other Google APIs in the future.

© 2020 Przemysław Kołodziejczyk