Securing OAuth clientId/clientSecret in AngularJS application Securing OAuth clientId/clientSecret in AngularJS application angularjs angularjs

Securing OAuth clientId/clientSecret in AngularJS application


Remember that OAuth is less about protecting against impersonation and more about protecting credentials. 3rd parties authenticated a user's identity for you without exposing the user's credentials. Since Tokens are not credentials, the amount of harm a hacker can do and his window to act are limited.

But OAuth is not inherently more secure for your application than regular username/pwd authentication. And on client-side apps, all your code is available for the world to see! Asyou mentioned, client-side encryption is a questionable strategy.


While there aren't established best practices for protecting client interactions, here are some approaches to minimize your exposure:

1) SSL: Silver bullet? Maybe. The more you can use SSL in your site and your requests, the safer your users' requests will be. I honestly believe all privileged requests should be made by encrypted requests.

2) Short Token Life-Span: The shorter the life-span of your Token, the less incentive/advantage of sniffing it.

OAuth 2.0 creates a constant chatter out of authentication by exchanging Authentication Tokens for Refresh Tokens for Authentication Tokens. You, as the developer are now developing a chatty app that does a lot of "what's your token, here's another token, ask me for a token, here's your new token... so what do you want?" ... "oops, time's up, where's your Refresh Token?"

If that sounds like a pain, it kind of is. OAuth 2.0 is designed to make the process easier for you the developer. But the important point is, the shorter the life span of your tokens, the harder for a hacker to maintain a fraudulent identity.Refresh Token reference

3) Enforce your Domain: Want to give sniffers less chance of abusing the chinks in your armor? Don't allow Cross Domain Requests!

Sure, we often have distributed environments. But if your Facade is on the Client's Domain, your exposure is lessened (word choice questionable).

Force the hacker to use your domain, limit their creativity.

4) Use 3rd party API's for maintaining you access as often as possible: Google and Facebook API's and Services have been unit tested, battle tested, and evolved. The more you can lean on them to maintain your user's Identity, the less work you will do and fewer chances you take.

5) Check IP addresses: Almost anything can be faked, but the hacker must know that IP Address is part of your validation. This is the least assured of all practices, but combined with 1,2, or more, the gaps for hackers to exploit get smaller and the payoffs for effort fade.

6) Use a "Secret" or 2nd parameter: You can pass your users more than tokens. You can pass your own Alter-Token.

Pretend it's an ID data being passed back and forth. Name the param in a non-obvious way. Make it a number (e.g. age, height, address). The important point is, your hacker knows little or nothing of what's being asked for on the other side!

You can throw a serious monkey-wrench by having 3 params that act as security.

7) Don't give error messages to inform the hacker they've been caught. Give timeout msgs rather than "Got You!" If the invaders don't realize the fraud was caught they don't adapt as well.


I can't say it enough -- SSL saves a lot of trouble.

Note: All client Providers I have seen allow access to their API's without exposing Secret. Secret should never be exposed on client.

  • Any data exposed on client can be gleamed
  • Any encryption algorithm you use, will be exposed on the client.


I came here looking for the answer to this very question - how to handle the secret/id in an SPA. I came up with my own solution that hides the secret in the server but I wanted to confirm what I was doing was best practice. So since answers avoid this I will explain my flow in hopes that it will help anyone out there.

Our architecture - we have a ruby server as the api server and an express server serving up the Angular app.

Normally all communication is simply done RESTfully thru the api so the node server is just serving static files and not really doing a whole lot.

Since we were at the point of implementing the login/signup flows I came across the - what was new to me - OAuth 2.0 flow of how to handle things.

Before we can make any requests to the server and the server will take us seriously we need to get ourselves the Bearer token. I chose to implement it as a node endpoint thus to hide the client secret inside the node server itself.

So our customer has entered all their juicy data and are redy to become a user in our app they hit the submit button.

  1. The app fires the request to the node server to get ourselves a yummy token that we can use as the Bearer. I chose to pass the client id as a GET request query parameter. First off I had both client id and secret in the node server but it felt like the id could/should be on the, well, client. So I went with this way.

  2. The node server receives the client id thru the GET request and then proceeds to fire the POST to the host(ruby api). Constructing the url + grant type + client id + client secret. Thus hiding the implementation from the world.

  3. The ruby server return a token for us to use which we then return to the client that initialized the signup request.

  4. The SPA now has a Bearer token which we can use in the header of the signup request.

Thus completing our flow and having a hidden cient secret from the world.

Since we have a token with a certain lifespan we also have a request error interceptor that will catch tokens that have expired and thus make a new token request and then refire the failed call.

I have chosen to use on the Angular side of things this lib for users flow.

https://github.com/sahat/satellizer

Its a super handy lib that gets all the boring boilerplate code that has to be written every time we want an app to have authentication thru email/password and also thru oauth....very handy.

So since this is my own interpretation of how to do such things - feedback is kindly requested.