我想仅向授权用户提供受保护的图像。因此,我在控制器中使用import UIKit
import Google
import GoogleSignIn
@UIApplicationMain
// [START appdelegate_interfaces]
class AppDelegate: UIResponder, UIApplicationDelegate, GIDSignInDelegate {
// [END appdelegate_interfaces]
var window: UIWindow?
// [START didfinishlaunching]
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Initialize sign-in
var configureError: NSError?
GGLContext.sharedInstance().configureWithError(&configureError)
assert(configureError == nil, "Error configuring Google services: \(configureError)")
GIDSignIn.sharedInstance().delegate = self
return true
}
// [END didfinishlaunching]
// [START openurl]
func application(_ application: UIApplication,
open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
return GIDSignIn.sharedInstance().handle(url,
sourceApplication: sourceApplication,
annotation: annotation)
}
// [END openurl]
@available(iOS 9.0, *)
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any]) -> Bool {
return GIDSignIn.sharedInstance().handle(url,
sourceApplication: options[UIApplicationOpenURLOptionsKey.sourceApplication] as? String,
annotation: options[UIApplicationOpenURLOptionsKey.annotation])
}
// [START signin_handler]
func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!,
withError error: Error!) {
if let error = error {
print("\(error.localizedDescription)")
// [START_EXCLUDE silent]
NotificationCenter.default.post(
name: Notification.Name(rawValue: "ToggleAuthUINotification"), object: nil, userInfo: nil)
// [END_EXCLUDE]
} else {
// Perform any operations on signed in user here.
let userId = user.userID // For client-side use only!
let idToken = user.authentication.idToken // Safe to send to the server
let fullName = user.profile.name
let givenName = user.profile.givenName
let familyName = user.profile.familyName
let email = user.profile.email
// [START_EXCLUDE]
NotificationCenter.default.post(
name: Notification.Name(rawValue: "ToggleAuthUINotification"),
object: nil,
userInfo: ["statusText": "Signed in user:\n\(fullName)"])
// [END_EXCLUDE]
}
}
// [END signin_handler]
// [START disconnect_handler]
func sign(_ signIn: GIDSignIn!, didDisconnectWith user: GIDGoogleUser!,
withError error: Error!) {
// Perform any operations when the user disconnects from app here.
// [START_EXCLUDE]
NotificationCenter.default.post(
name: Notification.Name(rawValue: "ToggleAuthUINotification"),
object: nil,
userInfo: ["statusText": "User has disconnected."])
// [END_EXCLUDE]
}
// [END disconnect_handler]
}
,它工作正常。但是,我想使用Nginx的XSendfile(X-Accel-Redirect)。我已经按照Nginx的documantation中的说明完成了相同的步骤。
此外,我已将BinaryFileResponse
添加到控制器。但是现在我一直在回复404。
以下是我的配置和代码:
Nginx的:
BinaryFileResponse::trustXSendfileTypeHeader();
Symfony Controller:
server {
listen 80;
listen 443 ssl http2;
server_name symfony.app;
root "/home/vagrant/Sites/Symfony/web";
index index.html index.htm index.php app.php app_dev.php;
charset utf-8;
location / {
try_files $uri $uri/ /app.php?$query_string;
}
location /images/ {
internal;
alias /home/vagrant/Sites/Symfony/app/media/images/listings/4/;
}
client_max_body_size 100m;
# DEV
location ~ ^/(app_dev|app_test|config)\.php(/|$) {
#fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_split_path_info ^(.+\.php)(/.*)$; # allows trailing slash after app_dev.php/
fastcgi_pass unix:/var/run/php/php7.1-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_intercept_errors off;
fastcgi_buffer_size 16k;
fastcgi_buffers 4 16k;
}
# PROD
location ~ ^/app\.php(/|$) {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php/php7.1-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_intercept_errors off;
fastcgi_buffer_size 16k;
fastcgi_buffers 4 16k;
internal;
}
location ~ /\.ht {
deny all;
}
ssl_certificate /etc/nginx/ssl/symfony.app.crt;
ssl_certificate_key /etc/nginx/ssl/symfony.app.key;
}
所以,去 http://symfony.app/images/1.jpg 应该返回一张图片,但是得到了一张图片。
答案 0 :(得分:1)
/images/
位置标记为内部,因此无法访问来自浏览器的外部请求。
http://nginx.org/en/docs/http/ngx_http_core_module.html#internal
我认为getPictureAction
的路径路径是/images/{id}
,并且无法访问它,因为nginx具有内部相同位置/images/
并返回404错误。
将nginx位置重命名为/images-internal/
:
location /images-internal/ {
internal;
alias /home/vagrant/Sites/Symfony/app/media/images/listings/4/;
}
将php代码更改为:
public function getPictureAction(Request $request, $id)
{
$dir = $this->get('kernel')->getRootDir() . '/' . 'media/images/listings/4/';
$path = $dir . $id;
$request->headers->set('X-Sendfile-Type', 'X-Accel-Redirect');
$request->headers->set('X-Accel-Mapping', $dir . '=/images-internal/');
BinaryFileResponse::trustXSendfileTypeHeader();
$response = new BinaryFileResponse($path);
$response->headers->set('Content-Type', 'image/jpg');
$response->setContentDisposition(ResponseHeaderBag::DISPOSITION_INLINE);
return $response;
}