I'm following this guide on how to write to my database with an authenticated user. I have set the rules properly and am able to post if all the writes are true just fine. When I pass the oauthToken I get when I follow this guide I get "Invalid claim "kid" in auth header". I've seen other questions with this result but I don't think they're doing the exact same things as I am nor are they using the same language.
So how do I authenticate properly? I can get the token and everything else just fine.
Current rule set:
{
"rules": {
"location": {
"$user_id": {
".read": all,
".write": "$user_id === auth.uid"
}
}
}
}
My code:
private function submitNewData(localId:String, authToken:String):void
{
var data:Object = new Object();
data.location = "w0.0rld";
data.description = "hello";
var request:URLRequest = new URLRequest("https://" + FIREBASE_PROJECT_ID + ".firebaseio.com/location/" + uid + ".json?auth=" + authToken);
request.data = JSON.stringify(data);
request.method = URLRequestMethod.POST;
var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, entrySent);
loader.load(request);
}
private function entrySent(event:flash.events.Event):void
{
trace(event.currentTarget.data); //Invalid claim 'kid' in auth header
}
Related
I am making a game on cocos2d-JS for facebook in which there is a requirement of sharing a screenshot of the game.
I am able to take the screenshot but now I am unable to upload it in the Parse.com server because it requires base64 format or byte array. I am unable to find any solution of converting Sprite in to this format.. Here's my code so result when I do addchild its coming proper .. I have also added my commented code so that it will help to understand that I have tried lot of things but couldnt achieve the same.
shareToSocialNetworking: function () {
cc.director.setNextDeltaTimeZero(true);
var newsize = cc.director.getVisibleSize();
var renderText = new cc.RenderTexture(newsize.width,newsize.height);
renderText.begin();
cc.director.getRunningScene().visit();
renderText.end();
var result = cc.Sprite.create(renderText.getSprite().getTexture());
result.flippedY = true;
this._mainViewNode.addChild(result,6000);
//renderText.saveToFile("screenshot.jpg",cc.IMAGE_FORMAT_PNG);
//var based = renderText.getSprite().getTexture().getStringForFormat().toString();
//var data = based.getData();
var file = new Parse.File("screen.jpg", { base64: this.getBase64(result) });
//var file = new Parse.File("screen.jpg", data, "image/png");
var self = this;
file.save().then(function() {
// The file has been saved to Parse.
alert(file.url);
this.onSharePictureInfoLink(file.url());
}, function(error) {
// The file either could not be read, or could not be saved to Parse.
});
//
//var ccImage = renderText.newCCImage();
//
//var str = ccImage.getData();
},
is there any workaround that can be done
there is a private variable called _cacheCanvas, which is the instance of the offscreen canvas
you can simply do renderText._cacheCanvas.toDataURL()
Here's how you can take the screnshot from cocos2d-JS
screenshot: function (fileName) {
var tex = new cc.RenderTexture(winSize.width, winSize.height, cc.Texture2D.PIXEL_FORMAT_RGBA8888);
tex.setPosition(cc.p(winSize.width / 2, winSize.height / 2));
tex.begin();
cc.director.getRunningScene().visit();
tex.end();
var imgPath = jsb.fileUtils.getWritablePath();
if (imgPath.length == 0) {
return;
}
var result = tex.saveToFile(fileName, cc.IMAGE_FORMAT_JPEG);
if (result) {
imgPath += fileName;
cc.log("save image:" + imgPath);
return imgPath;
}
return "";
}
then make a Java call from Javascript
public static void ScreenShot()
{
Bitmap imageBitmap = BitmapFactory.decodeFile(Cocos2dxHelper.getCocos2dxWritablePath() + "/" + "screenshot.png");
String fileHolder = "SampleFolder";
File filepathData = new File("/sdcard/" + fileHolder);
//~~~Create Dir
try {
if (!filepathData.exists())
{
filepathData.mkdirs();
filepathData.createNewFile();
FileWriter fw = new FileWriter(filepathData + fileHolder);
BufferedWriter out = new BufferedWriter(fw);
String toSave = String.valueOf(0);
out.write(toSave);
out.close();
}
}
catch (IOException e1) {
}
//~~~Create Image
File file = new File("/sdcard/" + "Your filename");
try
{
file.createNewFile();
FileOutputStream ostream = new FileOutputStream(file);
imageBitmap.compress(CompressFormat.PNG, 100, ostream);
ostream.close();
}
catch (Exception e) {}
Uri phototUri = Uri.fromFile(file);
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, phototUri);
//~~~Add Code Below
}
Do not forget to add permission for external storage
Below is the code taken from Arun Nagarajan's Example: I am tried the same code to check.. But Its not installing properly. (I removed my redirect url, client id and secret in the below). Please tell me what wrong in the below code.
var AUTHORIZE_URL = 'https://accounts.google.com/o/oauth2/auth';
var TOKEN_URL = 'https://accounts.google.com/o/oauth2/token';
var REDIRECT_URL = 'exec';
var tokenPropertyName = 'GOOGLE_OAUTH_TOKEN';
var CLIENT_ID = '';
var CLIENT_SECRET = '';
function doGet(e) {
var HTMLToOutput;
if(e.parameters.state){
var state = JSON.parse(e.parameters.state);
if(state.action === 'çreate'){
var meetingURL = createMeetingNotes();
HTMLToOutput = '<html><h1>Meeting notes document created!</h1> <click here to open</html>';
}
else if (state.ids){
var doc = DocsList.getFileById(state.ids[0]);
var url = doc.getContentAsString();
HTMLToOutput = '"<html><a href="' +url+'"</a></html>"';
}
else {
zipAndSend(state.ecportIds.Session.getEffectUser().getEmail());
HTMLToOutput = '"<html><h1>Email sent. Check your Inbox.</h1></html>"';
}
}
else if(e.parameters.code){
getAndStoreAccessToken(e.parameters.code);
HTMLToOutput = '<html><h1>App is installed. You can close this window now or navigate to your </h1>Google Drive</html>';
}
else {
HTMLToOutput = '<html><h1>Install this App into your google drive </h1>Click here to start install</html>';
}
return HtmlService.createHtmlOutput(HTMLToOutput);
}
function getURLForAuthorization() {
return AUTHORIZE_URL + '?response_type=code&client_id=' + CLIENT_ID + '&redirect_uri=' + REDIRECT_URL + '&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.install+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email';
}
function getAndStoreAccessToken(code) {
var parameters = { method : 'post',
payload : 'client_id='+ CLIENT_ID + '&client_secret=' + CLIENT_SECRET + '&grant_type=authorization.code&redirect_uri=' + REDIRECT_URL};
var response = UrlFetchApp.fetch(TOKEN_URL.parameters).getContentText();
var tokenResponse = JSON.parse(response);
UserProperties.getProperty(tokenPropertyName, tokenResponse.access_token);
}
function getUrlFetchOptions() {
return {'contentType' : 'application/json',
'headers' : {'Authorization': 'Bearer ' + UserProperties.getProperty(tokenPropertyName),
'Accept' : 'application/json'}};
}
function IsTokenValid() {
return UserProperties.getProperty(tokenPropertyName);
}
The error showing is: Bad request:undefined
I think the error is inside the function called : getAndStoreAccessToken.
var parameters = { method : 'post',
payload : 'client_id='+ CLIENT_ID + '&client_secret=' + CLIENT_SECRET + '&grant_type=authorization.code&redirect_uri=' + REDIRECT_URL};
Please tell me the correct url format for payload.
The error seems in this line -
var response = UrlFetchApp.fetch(TOKEN_URL.parameters).getContentText();
I think you want TOKEN_URL , parameters (note the comma)
First, if you are trying to access Google Drive from within google apps script, what is the purpose of the authorization? Google drive is available w/o authorization. Are you trying to make your application utilize the gDrive of other users (or on behalf of other users)?
Second, instead of manually performing the authorization, which is very hard to troubleshoot, you can take advantage of Class OAuthConfig which simplifies the authorization/request process. The only disadvantage is that OAuthConfig currently uses OAuth1.0 (which is currently deprecated). Although it's particular use is Fusion Tables, and not drive, this library makes great use of OAuthConfig and .fetch and I have used it to model my own OAuth functions. My example below works great. The googleAuth() function sets up the authorization and then the rest of the application can make authorized requests using UrlFetchApp.fetch(url,options) while google does all the authorization stuff in the background.
function googleAuth(oAuthFields) {
var oAuthConfig = UrlFetchApp.addOAuthService(oAuthFields.service);
oAuthConfig.setRequestTokenUrl("https://www.google.com/accounts/"+
"OAuthGetRequestToken?scope=" + oAuthFields.scope);
oAuthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
oAuthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
oAuthConfig.setConsumerKey(oAuthFields.clientId);
oAuthConfig.setConsumerSecret(oAuthFields.clientSecret);
return {oAuthServiceName:oAuthFields.service, oAuthUseToken:"always"};
}
function fusionRequest(methodType, sql, oAuthFields, contentType) {
var fetchArgs = OAL.googleAuth(oAuthFields);
var fetchUrl = oAuthFields.queryUrl;
fetchArgs.method = methodType;
if( methodType == 'GET' ) {
fetchUrl += '?sql=' + sql;
fetchArgs.payload = null;
} else{
fetchArgs.payload = 'sql='+sql;
}
if(contentType != null) fetchArgs.contentType = contentType;
Logger.log(UrlFetchApp.getRequest(oAuthFields.queryUrl, fetchArgs));
var fetchResult = UrlFetchApp.fetch(oAuthFields.queryUrl, fetchArgs);
if( methodType == 'GET' ) return JSON.parse(fetchResult.getContentText());
else return fetchResult.getContentText();
}
I hope someone will help me.
I have an API which is implemented with JSON web-services. I want to implement Login. A user is created and I need to have login the user. That is when I enter username and password it must log the user in .
I have read the tutsplus tutorial, but I am unable to authenticate the user. Can anyone help me out.
Here is the code I am using:
// create tab group
var tabGroup = Titanium.UI.createTabGroup();
var win1 = Titanium.UI.createWindow({
title:'Login',
backgroundColor:'#fff'
});
var username = Ti.UI.createTextField({
top:'10%',
borderRadius:3,
hintText:'username',
keyboardType:Titanium.UI.KEYBOARD_DEFAULT,
width:'80%',
height:'auto',
left:'10%',
right:'10%',
touchEnabled: true,
});
win1.add(username);
var pass = Ti.UI.createTextField({
top:'30%',
borderRadius:3,
hintText:'password',
keyboardType:Titanium.UI.KEYBOARD_DEFAULT,
width:'80%',
height:'auto',
left:'10%',
right:'10%',
touchEnabled: true,
passwordMask: true
});
win1.add(pass);
var loginBtn = Titanium.UI.createButton({
title:'Login',
top:'50%',
width:'60%',
height:'15%',
borderRadius:1,
font:{fontFamily:'Arial',fontWeight:'bold',fontSize:14}
});
win1.add(loginBtn);
var url = 'http://qudova.com/api.php?function=AuthenticateUser&u=ns.nadeem.m#gmail.com&p=qudovatest';
var json;
var loginReq = Titanium.Network.createHTTPClient();
loginBtn.addEventListener('click',function(e)
{
if (username.value != '' && pass.value != '')
{
// Here I will get the Token (asdfasdf....)
loginReq.open("GET",url);
authstr = 'Basic ' +Titanium.Utils.base64encode(username.value +':' +pass.value);
loginReq.setRequestHeader('Authorization', authstr);
loginReq.send();
}
else
{
alert("Username/Password are required");
}
});
loginReq.onload = function()
{
var jsonObject = JSON.parse(this.responseText);
// Here I have made a check if the Token is returned successfully it will alert the user that he authenticated
if (jsonObject.Token == "asdfadsfasdfadsf")
{
alert("Authenticated");
}
else
{
alert("response.message");
}
};
win1.open();
Thanks in Advance. Is my concept clear ?
You get a JSON array as response. So you should access jsonObject[0].Token.
// create tab group
var tabGroup = Titanium.UI.createTabGroup();
var win1 = Titanium.UI.createWindow({
title:'Login',
backgroundColor:'#fff'
});
var username = Ti.UI.createTextField({
top:'10%',
borderRadius:3,
hintText:'username',
keyboardType:Titanium.UI.KEYBOARD_DEFAULT,
width:'80%',
height:'auto',
left:'10%',
right:'10%',
touchEnabled: true,
});
win1.add(username);
var pass = Ti.UI.createTextField({
top:'30%',
borderRadius:3,
hintText:'password',
keyboardType:Titanium.UI.KEYBOARD_DEFAULT,
width:'80%',
height:'auto',
left:'10%',
right:'10%',
touchEnabled: true,
passwordMask: true
});
win1.add(pass);
var loginBtn = Titanium.UI.createButton({
title:'Login',
top:'50%',
width:'60%',
height:'15%',
borderRadius:1,
font:{fontFamily:'Arial',fontWeight:'bold',fontSize:14}
});
win1.add(loginBtn);
var url = 'http://qudova.com/api.php?function=AuthenticateUser&u=ns.nadeem.m#gmail.com&p=qudovatest';
var json;
var loginReq = Titanium.Network.createHTTPClient();
loginBtn.addEventListener('click',function(e)
{
if (username.value != '' && pass.value != '')
{
// Here I will get the Token (asdfasdf....)
loginReq.open("GET",url);
authstr = 'Basic ' +Titanium.Utils.base64encode(username.value +':' +pass.value);
loginReq.setRequestHeader('Authorization', authstr);
loginReq.send();
}
else
{
alert("Username/Password are required");
}
});
loginReq.onload = function()
{
var jsonObject = JSON.parse(this.responseText);
// Here I have made a check if the Token is returned successfully it will alert the user that he authenticated
if (jsonObject[0].Token === "asdfadsfasdfadsf")
{
alert("Authenticated");
}
else
{
alert("response.message");
}
};
win1.open();
Alternatively you can change your backend implementation, that the result will be an object instead of an array.
Nevertheless you should change your backend because at the moment it's possible to authenticate via plain GET parameters.
So I got this TitleWindow based Flex application where these windows are called by static functions written in them.
This is how it looks like when an entity needs do be created or edited from a DataGrid:
private function incluir():void {
NavioForm.incluir(dg.dataProvider);
}
private function atualizar():void {
NavioForm.atualizar(dg.dataProvider, dg.selectedIndex);
}
It's working perfectly from this side.
But since I used static functions, the code is starting to get a bit repetitive, as we can see on the examples below:
[Script tag of a CRUD form(incluir == include, atualizar == update, excluir == delete)]
...
[Bindable] private var navio:Navio;
public static function incluir(dataList:IList):void {
var form:NavioForm = new NavioForm();
form.action = FormWindow.ACTION_NEW + Navio.name;
form.navio = new Navio();
form.navio.lastUpdate = new Date();
form.result = function():void {
PortoService.obj.persistirNavio(form.navio).result(function(navio:Navio):void {
dataList.addItem(navio);
form.close();
}).fault(function(event:FaultEvent):void {
if(event.fault.faultString == 'duplicate key') {
Util.showError("This vessel's IMO is already present in our database.");
} else throw event.fault;
});
};
PopUp.add(form);
}
public static function atualizar(dataList:IList, index:int):void {
var form:NavioForm = new NavioForm();
form.action = FormWindow.ACTION_UPDATE + Navio.name;
form.imoRecieved = true;
form.navio = dataList[index];
PortoService.obj.obter(Navio, form.navio.key).result(function(navio:Navio):void {
form.navio = navio;
form.navio.lastUpdate = new Date();
});
form.result = function():void {
PortoService.obj.persistir(form.navio).result(function(navio:Navio):void {
dataList[index] = navio;
form.close();
}).fault(function(event:FaultEvent):void {
if(event.fault.faultString == 'duplicate key') {
Util.showError("This vessel's IMO is already present in our database.");
} else throw event.fault;
});
};
PopUp.add(form);
}
...
Script tag of another CRUD form:
...
[Bindable] private var vesselType:VesselType;
public static function incluir(dataList:IList):void {
var form:VesselTypeForm = new VesselTypeForm();
form.action = FormWindow.ACTION_NEW + VesselType.name;
form.vesselType = new VesselType();
form.result = function():void {
CoreService.obj.persistir(form.vesselType).result(function(type:VesselType):void {
dataList.addItem(type);
form.close();
});
};
PopUp.add(form);
}
public static function atualizar(dataList:IList, index:int):void {
var form:VesselTypeForm = new VesselTypeForm();
form.action = FormWindow.ACTION_UPDATE + VesselType.name;
form.vesselType = Util.clone(dataList[index]);
form.result = function():void {
CoreService.obj.persistir(form.vesselType).result(function(type:VesselType):void {
dataList[index] = type;
form.close();
});
};
form.deleteClick = function():void {
CoreService.obj.excluir(form.vesselType.key).result(function():void {
dataList.removeItemAt(index);
form.close();
});
};
PopUp.add(form);
}
So, is there a design pattern or any other technique to make this work?
You could make a crud component that you instantiate with all of the dynamic stuff such as the data provider location and it broadcasts events (or signals) that you assign appropriate listeners to.
I'm trying to upload file to box using v2. The only result i get is the error while uploading. I'm able to authenticate, get the auth token but not able to upload, I have given the code which i'm using. If i'm wrong anyway just correct me. Any help will be appreciated!!
public function upload(argFile:flash.filesystem.File):void{
argFile.addEventListener(Event.COMPLETE,
function onComplete(event:Event):void
{
trace("complete:"+event.toString());
}
);
argFile.addEventListener(IOErrorEvent.IO_ERROR,
function onIOError(event:IOErrorEvent):void
{
trace("Error:"+event.toString());
}
);
var url:String = "https://api.box.com/2.0/files/data";
// Setup the custom header
var customHeader:String = "BoxAuth api_key=" + api_key + "&auth_token=" + auth_token;
var headers:Array = [
new URLRequestHeader("Authorization", customHeader)
];
// create the url-vars
var urlVars:URLVariables = new URLVariables();
urlVars.filename1 = '#'+argFile.name;
urlVars.folder_id = "0";
// create the url-reqeust
var request:URLRequest = new URLRequest();
request.contentType = "application/octet-stream";
request.method = URLRequestMethod.POST;
// set ther url
request.url = url;
// set the header
request.requestHeaders = headers;
// set the vars
request.data = urlVars;
try {
argFile.upload(request);
} catch (e:Error)
{
trace(e.toString(), "Error (catch all)");
}
}