Creating a private API (authentication - Beyond the basics)

I’m writing an API to be accessed by my own mobile client (android). I’m trying to get my head around API authentication. Forgive me if I’m clueless :stuck_out_tongue:

So far, I’ve created a basic API with endpoints like:
@anvil.server.http_endpoint(’/ABC’, methods=[“POST”], authenticate_users=True)

This works fine for testing purposes but it means either all users in the system have access to the API directly or my app has a hard-coded (secret) user and all calls come from it.

I want to achieve the following:

  1. A new user should be able to create an account and login with Google from the client.

  2. The client should be able to make all calls to the API on behalf of the user.

  3. Use of the API should be restricted to my own approved client. In other words I don’t want an approved user to be able to access the API directly.

I’m really not sure how to get started with this. Links to relevant posts, projects, tutorials, and references are much appreciated.

I hadn’t gotten a response on this question so I’ve been digging around on my own.

All the examples and documentation seem to indicate that http endpoints with (authenticate_users=True) only use basic authentication.

I think what I need is for the android client to log in using google and pass a token securely through the API. Then I need to verify the token and create account and/or establish a session on the server.

I don’t see any examples how to do this and the anvil.google.auth doesn’t seem to be what I need.

Am I barking up the wrong tree?

Hi there:

  • Yes, authenticate_users=True uses HTTP Basic authentication only. If you want to use a different authentication system, you can build it yourself, but you’ll have to do it by hand!

  • Authenticating to Google via an app requires the mobile app to know how to sign into Google, not just the (Anvil) back-end service. This is why we can’t provide a one-click solution for Android that’s as easy as Anvil’s Google service :frowning:

    On Android, the official way is to use Google Sign-In for Android to sign into the app, and generate an ID token that you can then pass to the server and verify (using the Google Python SDK in an Anvil server module). The page I’ve linked to should help you get started.

  • It’s very difficult to restrict API usage to your own application. The application itself is in the hands of users, who can pull it apart, find out how it works, and call the APIs themselves! You can make this slightly harder by (eg) embedding a secret into your app, but it’s pretty quick to get that secret out of the app with a disassembler or transparent proxy.

1 Like

Thanks Meredydd. That’s helpful. I think we have the android client successfully obtaining and passing a token to my application now. I know I have to verify the token and I understand how to do that. After that, I’m still a bit fuzzy about how I actually log the user in.

Am I doing something to create a session so get_user() returns the correct row from the table? Or am I just finding a user in the table that corresponds to the token credentials and using it instead of whatever user would be returned from anvil.users.get_user()?

Presumably, for this kind of process, I wouldn’t use either authenticate_users=True or require_credentials=True in my endpoints but check for the presence of a token on every call.

Is that right?

Presumably, for this kind of process, I wouldn’t use either authenticate_users=True or require_credentials=True in my endpoints but check for the presence of a token on every call.

Yes, that’s the most sensible way!