问题
I'm using nginx to serve static files in an embedded system, with no CGI back-end. I have basic-authentication up with multiple username/passwords. I'd like to have a specific URI deliver different content based on the name of the currently authenticated user.
For instance, let's say a browser requested URI /index.html. If the browser was authenticated as user "developer", then it could be served the file /index_developer.html. If instead the browser was authenticated as "administrator" it could be served the file /index_administrator.html.
I only want this redirection to occur on a small set of files; most will be served as-is. I'd also need to block direct access to the actual files so that nobody could do an end-run around the system.
回答1:
First, there is variable $remote_user.
I've end up with following structure:
$ tree
.
├── _auth
│ ├── admin
│ │ ├── f
│ │ │ └── index.html
│ │ ├── hello.html
│ │ └── index.html
│ └── user
│ ├── f
│ │ └── index.html
│ └── index.html
├── f
│ └── x.html
├── hello.html
├── test.html
└── x
└── index.html
and this nginx config:
auth_basic "Restricted area";
auth_basic_user_file path/to/passwd/file;
root /path/to/root;
location / {
try_files /_auth/$remote_user$uri
/_auth/$remote_user$uri/index.html
$uri $uri/index.html =404;
}
location /_auth/ {
internal;
}
So request to /
will end up in /_auth/USER/index.html
, request to /test.html
will serve /test.html
. And request to /hello.html
will serve /_auth/admin/hello.html
for user admin
and /hello.html
for any other user.
Direct access to /_auth/..
is forbidden by internal
directive.
回答2:
Although I'm accepting Alexy Ten's answer, as his insight was what got me there, I ended up using a slightly different scheme.
Instead of having the user-specific files residing in a completely separate tree, I chose to have them live right next to the generic files, but adding a standard prefix of _user_<userName>_
. For instance, I might have the following two files in the webroot:
/scripts/menus.js
/scripts/_user_developer_menus.js
Then, if logged in as user "developer", a request for /scripts/menus.js would be served the second file, but with any other user the first file would be served.
Here is the core of my nginx configuration:
location ~ "^.*/_user_[^/]*$" {
internal;
}
location ~ "^(.*)/([^/]*)$" {
auth_basic_user_file /opt/product/cfg/nginx_conf/htpasswd;
try_files $1/_user_${remote_user}_$2$is_args$args
$1/_user_${remote_user}_$2/index.html$is_args$args
$1/$2$is_args$args
$1/$2/index.html$is_args$args
=404;
}
Since both locations are as specific (both regexes) they're searched in order. So, the first location blocks direct access to any of the _user_<userName>_
files. The second location matches any URL, with the path up to the file name left in $1
, and the file name left in $1
. Then, the try_files looks for a user-specific file, a user-specific directory, a common file, and a common directory, in that order, until it gives up with a 404 error.
回答3:
Simple root /path/to/root/$remote_user
is worked for me.
Note: if you use $document_root
in auth_basic_user_file
(like auth_basic_user_file $document_root/.htpasswd;
), then your .htpasswd
file should be in all subdirectories, not just root
$ tree -a
.
├── .htpasswd
├── user1
│ ├── hello1
│ └── .htpasswd -> ../.htpasswd
├── user2
│ ├── hello2
│ └── .htpasswd -> ../.htpasswd
└── user3
├── hello3
└── .htpasswd -> ../.htpasswd
来源:https://stackoverflow.com/questions/23506626/configure-nginx-to-return-different-files-to-different-authenticated-users-with