doumei4964
doumei4964
2019-01-28 08:56
浏览 97

如何验证javascript使用的REST API(因为代码是公共的)

Tl;dr: How to secure an internal API only used for AJAX calls on the website itself.

I have a REST API (PHP 7.2) that will be consumed by Javascript (client side)

Normally I build server-side apps (then I am in control and use either a secret or a token), however, with JS being public I am lost.

I wanted basic auth, cant because a user can view source and get the username and password.

I wanted to use a private key, again inspect element and the key is visible.

I wanted to whitelist the domain (PHP Side), the domain can be spoofed.

I wanted HMAC authentication, but again, inspect element and and see the HMAC message.

How do I secure a REST API that will be consumed by AJAX

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • douhui4831
    douhui4831 2019-01-28 21:34

    What you are looking for (or, in this case, NOT looking for) is CORS (Cross-Origin Resource Sharing).

    Simple way to do what you want - check the $_SERVER['REMOTE_ADDR'] against your server

    if ($_SERVER['REMOTE_ADDR'] != 'myserverIP') {
    

    (just so you know, that is secure - Reliability of PHP'S $_SERVER['REMOTE_ADDR'])

    Then, you can also force the 'Access-Control-Allow-Origin' to match your domain (a second-level security check - perhaps you want to keep things in a certain folder, etc.

    header("Access-Control-Allow-Origin: https://example.com");
    

    and various other specific access_control methods if you like......

    Here's a function I have been using (picked it up somewhere - most likely on SO and modified it a bit for my use...):

    somewhere in PHP (I use a 'codes.php' file to store and easily change the codes as needed, then include it so they are globally available)

    codes.php

    $spIP = 127.0.0.1; // whatever your IP is
    $splink = "https://your-domain-url.tld";
    

    then in a functions file

    function checkCORS()
    {
        global $spIP, $splink;
        if ($_SERVER['REMOTE_ADDR'] != $spIP) {
            return false;
        }
        header("Access-Control-Allow-Origin: $splink");
        header('Access-Control-Allow-Credentials: true');
        header('Access-Control-Max-Age: 6400');
        if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
            // you have to handle OPTIONS requests as some other method or you will get an error message
            if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
                header("Access-Control-Allow-Methods: POST");
            if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
                header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
            exit(0);
        }
        return true;
    }
    

    I'm using this on a secure-data program and so far, every way I've tried to hack into it hasn't worked (not saying there isn't some way in, but I can't find one..)

    A nice tool to test with is available at https://www.test-cors.org/

    点赞 评论

相关推荐