Categories
Uncategorized

Separating the front and rear end when deploying how to protect front-end code is not anonymous access

background

Now many projects have long isolated front and rear end of a way to develop and deploy. Nginx front-end code is deployed on the server, provide services directly from the static files nginx, nginx backend interface by doing a reverse proxy.

It would have been very reasonable deployment, but for some systems need to be logged in to visit, will be responsible for the safety of co-workers raised the following concerns:

index.html allow anonymous access, ulterior motives he not be based on index in the

It seems to solve this problem.

Thinking

To protect the distal home codes, a process request should be like this:

Home user-initiated request, the server finds that the user is not logged, jump to the login page;
    Home user-initiated request, the server finds that the user has logged in, the normal output the contents of the home page.

Note that this is the end of the service judge, not the client judgment.

There are not logged in judgment, there is no doubt that our back-end java to do things, but the home page is the html file in nginx below, when the user requests it yet-to-back here, then, how to judge?

Of course, you can move to the rear end of the front file under tomcat, served by tomcat, but this in turn back to the old, this is not a good way, not recommended.

In fact, without changing the deployment architecture of the premise, we simply by configuring with nginx and back-end interface, can achieve their goals.

Briefly, using the nginx rewrite + error_page instructions.

    First, the nginx rewrite instruction, the index of the request, the rear end of an interface to rewrite

    This interface in the back-end to determine whether the current user has logged in, if not logged in, return to 302 jumps, jumps to the authorization page to login

    If the backend interface determines the current user has logged in, it returns an error code to the Nginx (e.g. 404), using Nginx error_page, designated 404, the output of the content file index.html.

nginx exemplary configuration is as follows:

server {
       listen       80;
       server_name www.abc.com;
        recursive_error_pages on; #这个选项要开启
        location / {   
            root /path/to/front-end;
        }
        location /api #交由tomcat处理
        {
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header REMOTE-HOST $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto  $scheme;
            proxy_set_header   Cookie $http_cookie;
            proxy_pass http://localhost:9000;
        }

        location ~* ^(/|(/index\.html))$ {
            #未登录的情况下,不允许访问首页,注意这里rewrite到一个location,而不是直接proxy_pass到后端接口。因为我要在@fallback里利用queryString
            rewrite ^/(.*) /abcdefg?res=$request_uri; 
        }
        
        #
        location /abcdefg {
            proxy_pass http://localhost:9000/api/home/check-user?res=$request_uri;
            proxy_redirect off;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_intercept_errors on;
            error_page  404  = @fallback;
        }
        
        
        location @fallback {
            if ($query_string ~* ^res=([^&]*)) {
                    set $path $1;
                    rewrite ^ /local/scripts$path;
            }
        }
        location /local/scripts/ {
            internal; #nginx内部才有效的location,外部无法通过/local/scripts/这个路径访问
            alias /path/to/front-end/; #注意,最后有个/符号
            error_page  404  =200 /local/scripts/index.html;
        }
}

Example rear check-user interfaces are as follows:

@GetMapping("check-user")
public void checkUser(String res, HttpSession session, HttpServletRequest request, HttpServletResponse response) throws IOException {
    if(session.getAttribute("User") == null){
        response.sendRedirect("login?returnUrl=" + URLEncoder.encode(res, "UTF-8"));
        return;
    }
    response.setStatus(HttpStatus.SC_NOT_FOUND);
}

Leave a Reply