How to use new enhanced sessions in Parse with users created on cloud code? - rest

I was trying out the new enhanced revocable sessions in Parse on my Android app. It works well when logging in or signing up via email password or facebook but doesn't work well for custom authentication, e.g. google+.
I'm currently logging in the user using the cloud code which also creates the new user when signing up. This does not create a new Session object, that means the new enhanced sessions are not used and it still uses the legacy sessions.
I pass the session token back to client where using the become method the user logs in but it's the legacy sessions.
This feels like the feature is not complete but I would really like to move to the new enhanced sessions with my app. Has anyone worked with them yet? Are there any workarounds using the REST API or by creating the sessions manually and handling them manually? I looked into the JS API but it says it's only read only.
Here's the Blog post on Enhanced Sessions.
Where should I go next?

Yes, I found a solution but it's a workaround, works for my case because I don't support signing up with user/password.
Basically, the solution (cloud code) in semi pseudo-code is:
Fetch the user with master key
Check if user.getSessionToken() has value
if it has, return the session token and do a user.become() in the client as usual
if it's not, here the workaround, do the following:
yourPreviousPromiseInOrderToChainThem.then(function(user)
password = new Buffer(24);
_.times(24, function(i) {
password.set(i, _.random(0, 255));
});
password = password.toString('base64')
user.setPassword(password);
return user.save();
}).then(function(user) {
return Parse.User.logIn(user.get('username'), password)
}).then(function(user) {
var sessionToken = user.getSessionToken();
// Return the session token to the client as you've been doing with legacy sessions
})
That means, I'm changing the user password each time in order to make a remote login and, of course, I know thist can't be applied to all cases, it's enough for app because I don't support login with user/password (only third party logins) but I understand that maybe it's not for all cases.
I got the idea from this official Parse example.
I don't like this solution because I think is not a workaround, it's a mega hack but I think there is no other way to do it currently (either Parse.com or Parse-Server)
If you find other workaround, please, share it :)

Related

Parse Signup Problems

So, I wanted to create a new social media app using Swift and Parse. When I go to the Parse site, and click on dashboard, it gives me a login screen. I don't have an account, so I click on the "I don't have a parse account" button. When I click on that, it just takes me back to the home page. I did manage to get the code and frameworks and stuff that I needed from the docs, but that didn't quite work. It gave me this for the initialize code:
let configuration = ParseClientConfiguration {
$0.applicationId = "YOUR_APP_ID"
$0.server = "http://YOUR_PARSE_SERVER:1337/parse"
}
In the tutorial I'm watching, rather than "YOUR_APP_ID" and "http://YOUR_PARSE_SERVER:1337/parse" it just had a bunch of letters and numbers, which I would assume are the app ID and Parse server. My guess is, that I need an account to get those. Would that be correct? And, does anyone know why I can't seem to get an account? Thanks.
Parse.com is shutting down, so that's why you are not allowed to create new accounts on the service. Check the blog post.
They open sourced a nodeJS implementation, which you should definitely check out at link, and here is an example to get you started. You can easily use the deploy buttons to host the server on services like Heroku, AWS, Azure, etc. You can also deploy a server locally, for testing purposes.
Although it's true that Parse is discontinuing early next year, you can still setup a new app if you want to use the service for a shorter term project. Replace your code with the following.
Parse.setApplicationId("YOUR-APP-ID", clientKey: "YOUR-CLIENT-ID")
You can find your App ID and Client ID in your app's settings > security & keys.
EDIT: You definitely need an account for this to work.

App with no DB: You must call the "WebSecurity.InitializeDatabaseConnection" method before you call any other method of the "WebSecurity" class

First things first. I'm a complete OAuth newbie. This will be my first stab at it, and things are getting hairy...
I'm writing a single page application using Durandal & Web API.
The user needs to be able to login using any social network.
I don't have access to a database whatsoever, I have to call an unprotected 3rd party web service which I consume server-side, and need to protect using OAuth.
So I've managed to add the files to my solution which generates the login using facebook contol/button (created a new MVC4 web application, and did a manual copy and paste of all the auth related files, updated bootstrappers etc..), and the code seems to work for the most part.
When facebook redirects back to
[AllowAnonymous]
public ActionResult ExternalLoginCallback(string returnUrl)
{
AuthenticationResult result = OAuthWebSecurity.VerifyAuthentication(this.Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl }));
if (!result.IsSuccessful)
{
return this.RedirectToAction("ExternalLoginFailure");
}
if (OAuthWebSecurity.Login(result.Provider, result.ProviderUserId, createPersistentCookie: false))
{
return this.RedirectToLocal(returnUrl);
}
//code removed for brevity ....
}
I get the error specified once the following line tries to execute.
OAuthWebSecurity.Login(result.Provider, result.ProviderUserId, createPersistentCookie: false)
I've removed the [InitializeSimpleMembership] attribute from the controller, as I don't have a database.
Please forgive me if this is the dumbest question ever, but...
Why does the login fail? I mean at that point, isn't the app trying to log into facebook, why does it need a databse? Or am I correct in saying I can remove/replace that code section, with a login/authorise call on the web-service I'm using?
Not the dumbest question ever. Not by a long shot. But you are getting the error because your membership provider is still set to use the SimpleMembershipProvider and OAuthWebSecurity will use the default membership provider. If you don't want to use a database you will have to create or find a different membership provider to use.
EDIT:
I know you said you don't have access to a DB but if you can use SQL Compact you can just stick with the default SimpleMembershipProvider(check out Hanselman's blog) or DevArt has a SQLLite provider. Also the MemFlex Project has a RavenDb provider. If none of those work I think you might just have to write your own.

GitHub OAuth in lua

I am working on a library in LUA for an ipad app called Codea. I'm trying to figure out to use OAuth for GitHub Gists. Only part that i can not figure out is how to get an Auth token via code. I used curl in terminal to get myself a token but this seems to be to much work for other users.
I've read through the github api docs multiple times but I cant figure out how to get a Token programmatically. I've tried to duplicate the method I've used to GET and POST gists but it does not seem to work. I'm not sure how to pass the username and password.
I'm creating a table with the needed params then encoding it in json. Everything I try gets a 404 error or 500 error. Thank you all in advance.
local url = "https://api.github.com/authorizations"
local d = {}
d.scopes = {"gist"}
d.note = "AutoGist Codea"
projectAuth = json.encode(d)
opts = { data = projectAuth }
opts.method = "POST"
opts.headers = {Authorization = "basic " .."username:password"}
http.request(url,successCallback,failedCallback,opts)
Scopes are coming, but only in Q4 2013.
See "OAuth changes coming" (October 2013, by Tim Cleam - tclem):
Starting today, we are returning granted scopes as part of the access_token response.
For example, if you are making a POST with the application/json mime-type you’ll see an additional field for the granted scopes.
{
"access_token":"e72e16c7e42f292c6912e7710c838347ae178b4a",
"scope":"repo,gist",
"token_type":"bearer"
}
Right now, these scopes will be identical to what you requested, but we are moving towards a feature set that will allow GitHub users to edit their scopes, effectively granting your application less access than you originally requested.
You should be aware of this possibility and adjust your application behavior accordingly.
Some things to watch out for and keep in mind:
Most third party applications using GitHub OAuth to identify users have the best success in adoption by starting out with a request for the minimum access that the application can possibly get away with.
Something like no scopes or just user:email is very sane.
It is important to handle the error cases where a users chooses to grant you less access than you originally requested.
Now that we are surfacing the granted scopes on the access_token response, applications can warn or otherwise communicate with their users that they will see reduced functionality or be unable to perform some actions.
Applications can always send users back through the flow again to get additional permission, but don’t forget that users can always say no.

How to have users 'reconnect' with soundcloud on each page reload?

I'm using the Javascript SDK inside a node.js (Express) App.
Connecting Users works fine, but the connection does not persist between page reloads.
Is this the default behaviour, or is the User supposed to stay connected in new requests?
Do I have to use OAuth token authentication and if so, how can this be done with the JS-SDK?
Inside the "Permission"-Popup, Users are already logged in with soundlcoud, though.
(just have to click the "connect" button each time)
Figured I'd share my answer for those who are unsatisfied with the current answers for automated oauth:
Retrieving access_token:
I had to define get and set cookie functions and then I use the functions to set and retrieve a function holding the access token. I'm not going to give these functions for conciseness but you can easily find them with a google search. I then use this line of code to get the SC access token (once the user has authenticated for the first time)
SC.accessToken()
Setting token:
So this is kind of just an elephant in the room in my opinion that for some reason no one has mentioned. How in the **** do you connect w/ SC using the access token? Do you set it as oauth param? On each call pass it? Well, after experimenting with putting the parameter in every single place I could think, I found out you have to do something like this:
SC.initialize({
client_id: '[removed for security reasons]',
client_secret: '[removed for security reasons]',
redirect_uri: '[removed for security reasons]',
access_token: getCookie("sc_lm2"),
scope: 'non-expiring'
});
//Where "sc_lm2" is the name of my cookie
Hope the helps! Took me a while to figure this out for such a simple thing
EDIT
Using PHP and Wordpress:
$json = wp_remote_get("http://api.soundcloud.com/users/[user_id]/tracks.json?client_id=[client_id]");
$soundcloudData = json_decode($json['body'],true);
(substitue cURL functionality if you're not using Wordpress). #krafty I assume you would just change the endpoint from "/tracks" to "/users" but I can't say I have ever really needed to grab anything but tracks using the Soundcloud API. Hope this helps, though I'm not sure I fully understand what it is that you are trying to accomplish (or rather, how exactly you're going about it) - are you trying to allow user logins? If you want to explain fully what you're trying to accomplish and the steps you're taking I'd be happy to take a crack at it.
Yep, this is the way to do it, officially. :)
For the Next SoundCloud site, we store the token in localStorage (until the user logs out, of course). In each AJAX request to the API from the front end, we put the oauth token in a request header:
jqXHR.setRequestHeader('Authorization', 'OAuth ' + the_oauth_token);

Refresh expired access tokens using serverside flow automatically

Well there seems to be quite a bit of confusion on this topic and I am struggling to get a clear answer, so here is my question...
I am using the serverside flow to obtain access tokens for my web app, I previously used offline_access which is now being depreciated so I need a way to refresh the token in the following situations:
1) User changes FB password
2) Token expires naturally
My app posts results to users FB walls so the refresh needs to be done automatically by our server (no cookies or OAuth dialogs)
I thought I could try to use the new endpoint described here
http://developers.facebook.com/roadmap/offline-access-removal/
, with the following piece of code (Java):
public static String refreshFBAccessToken(String existingAccessToken)
throws Exception{
//Currently not working
String refreshUrl = "https://graph.facebook.com/oauth/access_token?
client_id="+FacebookApp.appId+"
&client_secret="+FacebookApp.appSecret+"
&grant_type=fb_exchange_token
&fb_exchange_token="+existingAccessToken;
URL url = new URL(refreshUrl);
URI uri = new URI(url.getProtocol(), url.getHost(), url.getPath(),
url.getQuery(), null);
String result = readURL(uri.toURL());
String[] resultSplited = result.split("&");
return resultSplited[0].split("=")[1];
}
But this doesnt seem to work (I get a response 400), and when I re-read the documentation it seems this endpoint is used for tokens obtained using the client-side flow only...
So what about the serverside flow....?
Can someone tell me if the approach above is correct or there is another way?
Many thanks
From what I understand there is no server side flow for refreshing tokens.
The refresh token call needs to include the response of the user authentication process which is a short lived token.
You will need to include the refresh token process as part of the user login flow or if this doesn't work for your setup you will need to email the user asking them to come back!
I dont know java but syntax is very much like C#, so I can say,you are doing everything right.
But I doubt what does this function readURL do ?
If it works like get_file_contents() of php (i.e. if it does an HTTP get) , I guess thats not a right way to do .
Based on my experience on google's refresh token method, I think you should do an HTTP POST instead of HTTP GET to given url.