[Resolved] API Key in Backendless?!


#1

So I’ve been testing and testing with Backendless and Dropsource to build an app for a restaurant group. There are parts of the app that will need to pull information from our Backendless API without any type of user authentication. Example: we have a 9 locations and I have a table for our locations. The user can open the “Locations” tab and all the locations populate by a general API call. They can then tap a specific location to get more information about the location. However, I’m running into some issues the API’s authentication. I have tried to set the app ID and API key as a device variable during the App Launch lifecycle but when I open the Locations page I get an error returned from the API stating " Non existing user token" In the same message it shows the user token(API key) that it’s using and it matches the API key in my Backendless environment. I’m not quite sure what to do here. I can post some images but wanted to get some feedback before I posted a ton of information.

@markpiller I’m not sure of best practice here. Everything was working for a while and then I started getting this error. I have permissions for the NotAuthenticatedUser role in this specific table set to allow all permission types.

Update: I removed the App Launched lifecycle event and did a ‘Set Value’ during the API request of the Page Loaded event and now the API call goes through with no errors. However, selecting a cell in the collection view should take the user to a page with the location details. Once the new page opens the API call runs to pull the data. At that point I get the " Non existing user token" error again.


#2

I think what’s confusing me here and possibly the Dropsource application is that the file path is clearly defined the in Swagger documentation. That file path has the APP ID and the API Key in it. The url that is being accessed for the table doesn’t require any type of API Key header or token header. At least not when I test in Postman. It’s seems that when I run my app for the first time, the API call will work just fine and the request header doesn’t show any token. Then when I run the api call again by a refresh button on the same page or going to another page in the app to ask for different data, the same “Non existing user token” error presents itself. I must be an idiot because I have no clue what to do at this point.


#3

Interesting use case here. I wonder if on the backendless side of things, you can have it ignore any api key that’s sent with the request when it isn’t required for data? In Dropsource, when you’re setting up a API’s key via Swagger and all that, it’s going to be set in the requests as a default since that’s more or less the basic api operation that when a key is stored, we expect it necessary for all requests. I don’t think we have a means to cherry pick bit of information unless there’s a way to specify this within the Swagger doc based on each API request’s setup.

@markpiller Have you ever encountered a use case like this? I’m guessing the error is basically coming from the fact we’re sending the stored key along with requests that don’t require it and this is confusing the backend here? That’s my guess on this 1 so far


#4

Thanks Wade. Would a build ID help to see exactly what I’m seeing? I can send a build ID with short video/screenshots of what is returned for me. Also, I retooled another test environment and I set that one to only allow a user to view all of the pages once they were authenticated and every subsequent API call afterwards works with no issues. It seems that just passing the API key isn’t enough. It has to be the user token that is returned from the authentication.


#5

Ah yes, I’m getting my terms mixed up actually. I meant the Access_Token the whole time. Yes the test environment setup and using an Access_Token is how I would expect this to be used. Can that setup work for your workflow. That would be the ideal way to go I would think.


#6

So for my workflow it wouldn’t work to have to authenticate a user before they view certain things. I want to have a couple of pages in the app that are open to guests. Then there will be a couple of other pages that are going to require authentication. I’ll take you through the workflow:

  1. End user downloads app
  2. They can view our locations and events pages(as well as some other static data inside of the app)
  3. If they are members of our beer club(points based club; we give out prizes based on level in the club) then they will login
  4. Once logged in they will have access to more in depth pages of beer club data and their profile. We have 2 other open API’s that we will be using. One from our POS provider that handles all of our loyalty points tracking and the other is from a beer database that will provide more information on our beer lists that each member has purchased.
  5. Also authenticated users will get push notifications based on their favorite locations and promotional discounts.

Not really sure how to proceed. Maybe I could adjust the API spec file to remove the security definitions on the 2 tables I want to allow nonauthenticated users? I don’t know if that will work or not.


#7

Thank you for this clarification. I haven’t had a use case to this extent so my guidance is limited. You will have to do a little experimentation. Mark might have some insight on how the backend can handle this OR perhaps you have the ability to set this non-auth ability up in your Swagger based on routes perhaps? I wonder if you can create a non-auth required route up for this use within the same Swagger.

The other “perhaps hacky” way I could think of is maybe having a dual swagger file for 1 API? In 1 version, you could implement things without auth setup and in the other, with auth setup. I’m not entirely positive what reaction your project will have with a setup like this as I haven’t tested such a use case but it could be worth testing if other options aren’t solving your needs here.

I will be curious to learn how this implementation works as I can see this being something others would employ as a means to offer info from an API prior to a user setting up an account in workflows such as yours.


#8

Alright! So I removed the security definition from the API spec file. With no authentication, I can run as many API calls as I would like. It looks like this works just fine. So it’s definitely the user-token payload that puts a damper on things when trying to make a NotAuthenticated user calls. I’ll need to test this out more but I guess in theory I could potentially do what you said and have 2 different API specs. One for authenticated calls and one for not.

However, I would like to not have to create that kind of work around and have the ability to do both in one setup. Maybe Mark has some insight on a better way to do this. I’m sure I could add a non auth parameter to certain paths of the swagger doc but I would like to take advantage of the “out of the box” api generation that Backendless provides. Thanks for your help my friend. This is super helpful to let me test functionality of workflow for guest end users.


#9

I’m glad there’s at least 1 way to do it. I also agree, not ideal to play a 2 file strategy out like that. If you can work with 1 file or handle the ignoring of an Access_Token on backendless’s side, that probably a more ideal setup here.

Happy to help, Matt! Thanks for reaching out.


#10

Hi @matt,

I could not figure out what specific API call resulted in the error. Was it data retrieval from the database or file download?

In any case, you do not need to set APP ID or API KEY in your Dropsource logic. The API Doc generated by Backendless includes the ID and Key and they are automatically handled for you.

Regards,
Mark


#11

Hey @markpiller

It was data retrieval. All I’m attempting to do is a GET on all my locations in a table called “locations”. The problem is that the API spec file has the user-token security definition. Maybe I wasn’t doing something right but you have to set the authentication method of the api call in Dropsource. Normally if I were authenticating a user I would set the device variable of usertoken to the usertoken retuned is the 200 code data. However, I’m not logging any user in so I just need to make the call as a notauthenticateduser and I can’t seem to figure out how to set the authentication of the API for that type of call. Does that make sense?


#12

Hi @matt,

Yes, I know exactly what you’re talking about. All you need to do is this:

  1. Declare a device variable of type String, you can call the variable anything you want, let’s say it is userToken
  2. For the API you added, add the authentication method:
    Editor%20-%20Dropsource%202019-05-03%2008-13-05
  3. Then assign the device variable to the userTokenHeader:

That’s all it takes. If you do not handle user logins in your app, you do not need to do anything special with the userToken variable. However, if you handle logins, then the response for the Backendless Login API, will include a value for userToken and it must be assigned to the device variable.

Regards,
Mark


#13

Hey @markpiller,

So just set the variable to an empty string? Maybe that was the issue. I think I was setting my device variable to the API key the whole time. Now that I think about it the user-token isn’t the api key.


#14

I set it to an empty string and it works perfectly. I can’t believe with all of the things I tried, that wasn’t one of them. Thanks Mark!


#15

Yes, just an empty string. A user-token is sort of a session ID, it identifies the currently logged user on the backend, that way we can apply all the security policies.


#16

Ahh that’s a great solve there. I didn’t think about an empty string either. I will keep this noted now for when it comes up in the future.