Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
279 views
in Technique[技术] by (71.8m points)

php - securing a REST API accessible from Android

We're building a game for Android, which needs access to web services - so we wrote a RESTful API in PHP that runs on our own server. What the API offers is: creating user, logging in, downloading games, retrieving game list, submitting score... etc. Now I'm thinking, if some experienced user gets the URL format of the API - s/he will be able to trash the system in many ways:

  • Create a script & run it to create automatic users - I think I can prevent it by CAPTCHA or someting like that. But again, captcha will annoy game players.
  • Malicious user logs in using his browser, downloads game & then submits score as he wish - all via calling the API by simply typing it from his browser. I assume malicious user somehow knows API urls to call - by sniffing when the application was making HTTP requests.
  • I need to ensure that requests are made only from Android device that installed the game. (The game will be free)

Now How do I prevent such abuses?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I think you will never be able to hide the urls being called by the application (if I am running a root-ed android phone, I should be able to spy on all network traffic)

But your real problem is that you need to authenticate your api in some way.

One way would be to implement OAUTH, but maybe this'd be overkill.

If you want a simple mechanism, how about this;

  1. create a secret key
  2. build the api request (eg. https://my.example.com/users/23?fields=name,email)
  3. hash this request path + plus your secret key (eg. md5(url+secret_key) == "a3c2fe167")
  4. add this hash to your request (now it is https://.....?fields=name,email&hash=a3c2fe167)
  5. on the api end, do the same conversion (remove the hash param)
  6. check the md5 of the url and the secret key

As long as the secret remains secret, no one can forge your requests.

Example (in pseudo-code):

Android side:

SECRET_KEY = "abc123"

def call_api_with_secret(url, params)
  # create the hash to sign the request
  hash = MD5.hash(SECRET_KEY, url, params)

  # call the api with the added hash
  call_api(url+"&hash=#{hash}", params)
end

Server side:

SECRET_KEY = "abc123"

def receive_from_api(url, params)
  # retrieve the hash
  url_without_hash, received_hash = retrieve_and_remove_hash(url)

  # check the hash
  expected_hash = MD5.hash(SECRET_KEY, url_without_hash, params)

  if (expected_hash != received_hash)
    raise our exception!
  end

  # now do the usual stuff
end

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...