Start a new topic

Business Logic script for authenticating Pusher private channel

After many hours of guessing and checking, here is the correct recipe for writing a private channel authentication custom endpoint for Pusher.com



//Add this to your custom endpoint code

var pusherAppKey = "YOUR_PUSHER_APP_KEY";

var pusherAppSecret = "YOUR_PUSHER_SECRET";

var socketID = request.body['socket_id'];//socket & channel come in as body parameters, so if you need to add body data from your client, append "&field=value" - style

var channelName = request.body['channel_name'];

//You define a custom header name

var authHeader = request.headers['x-mycustom-authtokenheader'];



//do your custom backend authentication here.

// return response.complete(401); //403? to deny access



//This hmac sha-256 is copied from https://github.com/Caligatio/jsSHA

//The bug question here is: is there an HMAC SHA-256 already implemented in a library already included in Kinvey?



(function(B){function r(a,c,b){var f=0,e=[0],g="",h=null,g=b||"UTF8";if("UTF8"!==g&&"UTF16"!==g)throw"encoding must be UTF8 or UTF16";if("HEX"===c){if(0!==a.length%2)throw"srcString of HEX type must be in byte increments";h=u(a);f=h.binLen;e=h.value}else if("ASCII"===c||"TEXT"===c)h=v(a,g),f=h.binLen,e=h.value;else if("B64"===c)h=w(a),f=h.binLen,e=h.value;else throw"inputFormat must be HEX, TEXT, ASCII, or B64";this.getHash=function(a,c,b,g){var h=null,d=e.slice(),l=f,m;3===arguments.length?"number"!==

typeof b&&(g=b,b=1):2===arguments.length&&(b=1);if(b!==parseInt(b,10)||1>b)throw"numRounds must a integer >= 1";switch(c){case "HEX":h=x;break;case "B64":h=y;break;default:throw"format must be HEX or B64";}if("SHA-224"===a)for(m=0;m
}if("SHA-224"===c)l=64,n=224;else if("SHA-256"===c)l=64,n=256;else throw"Chosen SHA variant is not supported";if("HEX"===b)d=u(a),m=d.binLen,d=d.value;else if("ASCII"===b||"TEXT"===b)d=v(a,g),m=d.binLen,d=d.value;else if("B64"===b)d=w(a),m=d.binLen,d=d.value;else throw"inputFormat must be HEX, TEXT, ASCII, or B64";a=8*l;b=l/4-1;lm/8&&(d[b]&=4294967040);for(l=0;l
z(k))}}function v(a,c){var b=[],f,e=[],g=0,h;if("UTF8"===c)for(h=0;h>>12,e[1]=128|(f&4032)>>>6,e[2]=128|f&63):128>>6,e[1]=128|f&63):e[0]=f,f=0;f>>2]|=e[f]>>2]|=a.charCodeAt(h)
b;f+=2){e=parseInt(a.substr(f,2),16);if(isNaN(e))throw"String of HEX type contains invalid characters";c[f>>>3]|=e
h|=f>2]|=(h>>>16-8*g&255)>>2]>>>8*(3-e%4),b+="0123456789abcdef".charAt(g>>>4&15)+"0123456789abcdef".charAt(g&15);return c.outputUpper?b.toUpperCase():b}function y(a,c){var b="",f=4*a.length,e,g,h;for(e=0;e>>2]>>>8*(3-e%4)&255)>>2]>>>8*(3-(e+1)%4)&255)>>2]>>>8*(3-(e+2)%4)&255,g=0;4>g;g+=1)b=8*e+6*g
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(h>>>6*(3-g)&63):b+c.b64Pad;return b}function z(a){var c={outputUpper:!1,b64Pad:"="};try{a.hasOwnProperty("outputUpper")&&(c.outputUpper=a.outputUpper),a.hasOwnProperty("b64Pad")&&(c.b64Pad=a.b64Pad)}catch(b){}if("boolean"!==typeof c.outputUpper)throw"Invalid outputUpper formatting option";if("string"!==typeof c.b64Pad)throw"Invalid b64Pad formatting option";return c}function k(a,c){return a>>>c|a
c^~a&b}function J(a,c,b){return a&c^a&b^c&b}function K(a){return k(a,2)^k(a,13)^k(a,22)}function L(a){return k(a,6)^k(a,11)^k(a,25)}function M(a){return k(a,7)^k(a,18)^a>>>3}function N(a){return k(a,17)^k(a,19)^a>>>10}function O(a,c){var b=(a&65535)+(c&65535);return((a>>>16)+(c>>>16)+(b>>>16)&65535)>>16)+(c>>>16)+(b>>>16)+(f>>>16)+(e>>>16)&65535)
65535)+(f&65535)+(e&65535);return((a>>>16)+(c>>>16)+(b>>>16)+(f>>>16)+(e>>>16)+(g>>>16)&65535)
3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298];d=[3238371032,914150663,812702999,4144912697,4290775857,1750603025,1694076839,3204075428];f=[1779033703,3144134277,1013904242,

2773480762,1359893119,2600822924,528734635,1541459225];if("SHA-224"===b||"SHA-256"===b)l=64,A=16,s=1,G=Number,p=O,v=P,w=Q,x=M,y=N,z=K,D=L,F=J,E=I,d="SHA-224"===b?d:f;else throw"Unexpected error in SHA-2 implementation";a[c>>>5]|=128>>9n?new G(a[n*s+m],a[n*s+m+1]):v(y(t[n-2]),t[n-7],x(t[n-15]),t[n-16]),C=w(r,D(h),E(h,k,q),B[n],t[n]),u=p(z(c),F(c,f,e)),r=q,q=k,k=

h,h=p(g,C),g=e,e=f,f=c,c=p(C,u);d[0]=p(c,d[0]);d[1]=p(f,d[1]);d[2]=p(e,d[2]);d[3]=p(g,d[3]);d[4]=p(h,d[4]);d[5]=p(k,d[5]);d[6]=p(q,d[6]);d[7]=p(r,d[7])}if("SHA-224"===b)a=[d[0],d[1],d[2],d[3],d[4],d[5],d[6]];else if("SHA-256"===b)a=d;else throw"Unexpected error in SHA-2 implementation";return a}"function"===typeof define&&typeof define.amd?define(function(){return r}):"undefined"!==typeof exports?"undefined"!==typeof module&&module.exports?module.exports=exports=r:exports=r:B.jsSHA=r})(this);



//resuming useful code.

var shaObj = new jsSHA(socketID + ":" + channelName, "TEXT");

var hmac = shaObj.getHMAC(pusherAppSecret, "TEXT", "SHA-256", "HEX");

response.body={"auth":pusherAppKey +":" + hmac};

response.headers['Content-Type'] = "application/json"; //I'm not 100% certain this line is required.

return response.complete(201);

Awesome,



Thanks for your hard work on this Ben, this will come in handy if anyone ever wants to use this service.



Have a nice afternoon
As a side note, In the URL sent to Pusher.com for it to call, there's the standard stuff about kinvey api, i.e. https://baas.kinvey.com/rpc/:appkey/custom/:customendpointname, but you need user authentication to access your Kinvey custom endpoint. Manually add auth tokens for other kinds of log in to the headers in the Pusher framework's callback -pusher:willAuthorizeChannel:withRequest: by modifying the mutable url request:



NSString* authHeader = [NSString stringWithFormat:@"%@:%@", userName, userPassword];

NSString* base64Data = [[authHeader dataUsingEncoding:NSUTF8StringEncoding] base64EncodedStringWithOptions:0];

[request setValue:[NSString stringWithFormat:@"Basic %@", base64Data] forHTTPHeaderField:@"Authorization"];
Login or Signup to post a comment