Bắt tất cả các tuyến đường NGOẠI TRỪ cho / đăng nhập


83

Tôi hiện đang viết một API sẽ yêu cầu người dùng chuyển mã thông báo xác thực trong tiêu đề của mỗi yêu cầu. Bây giờ tôi biết tôi có thể tạo một tuyến đường hàng hóa nói

app.get('/*', function(req,res){

});

nhưng tôi đã tự hỏi làm thế nào để tạo ra nó để nó loại trừ các tuyến đường nhất định như /loginhoặc /?


Ví dụ: Yêu cầu xác thực trên tất cả các tuyến ngoại trừ / đăng nhập/ đăng ký . (Vì mọi người đang thắc mắc tại sao bạn lại hỏi câu hỏi này)
a20

Câu trả lời:


124

Tôi không chắc bạn muốn điều gì xảy ra khi người dùng truy cập /loginhoặc /, nhưng bạn có thể tạo các tuyến đường riêng cho những người đó; nếu bạn khai báo chúng trước toàn bộ thư, họ sẽ nhận được lần đầu tiên trong việc xử lý các yêu cầu đến:

app.get('/login', function(req, res) {
  ...
});

app.get('/', function(req, res) {
  ...
});

app.get('*', function(req, res) {
  ...
});

1
Điều này sẽ chỉ hoạt động cho "GET" phải không? Vì một số lý do, tôi không thể làm cho câu trả lời này app.use(bao gồm các phương pháp khác).
SSH này

4
@SSĐiều này Tôi nghĩ rằng với phiên bản mới nhất của Express (v4), app.use('*', ...)cũng sẽ hoạt động. Nhưng sử dụng app.all('*', ...)là thích hợp hơn trong trường hợp này.
robertklep

@JulienMartin chỉ thử nghiệm, trông giống như nó hoạt động như mong đợi với Express v4.16.3
robertklep

app.usethêm phần mềm trung gian, theo thiết kế chủ yếu chuyển yêu cầu đến trình xử lý tiếp theo trong chuỗi (sử dụng đối số bổ sung next).
Stijn de Witt

45

Bạn luôn có thể đặt lộ trình nhận toàn bộ sau những lộ trình bạn muốn loại trừ (xem câu trả lời robertklep ).

Nhưng đôi khi bạn chỉ đơn giản là không muốn quan tâm đến thứ tự của các tuyến đường của bạn. Trong trường hợp này, bạn vẫn có thể làm những gì bạn muốn:

app.get('*', function(req, res, next) {
  if (req.url === '/' || req.url === '/login') return next();
  ...
});

1
.get ( '*', function (req, res, bên cạnh).
Oliver Dixon

2
@iLoveUnicorns thanx! Tại sao bạn không chỉnh sửa bài viết của tôi?
Leonid Beschastny

Nếu các quy tắc khác là Trước cái đó, có cần gọi tiếp theo không?
Sandburg

1
Phần mềm trung gian @Sandburg nên gọi next()để chuyển thực thi cho phần mềm trung gian tiếp theo hoặc gửi một số phản hồi để hoàn tất xử lý yêu cầu. Nếu không, yêu cầu sẽ bị treo. Nếu phần mềm trung gian cuối cùng trong ngăn xếp được gọi next()thì express sẽ gửi phản hồi mặc định "404 Không tìm thấy". next()Ví dụ: thay vì gọi, bạn có thể gọi res.status(400).end()để kết thúc xử lý yêu cầu với phản hồi "400 Yêu cầu không hợp lệ".
Leonid Beschastny

23

Nếu bạn muốn xác thực thông tin đăng nhập hoặc tính xác thực trong mọi yêu cầu, bạn nên sử dụng tính năng Định tuyến nhanh "tất cả", bạn có thể sử dụng nó như sau:

app.all('/api/*', function(req, res, next){
    console.log('General Validations');
    next();
});

Bạn có thể đặt nó trước bất kỳ nội dung Định tuyến nào.

Lưu ý rằng trong trường hợp này tôi đã sử dụng "/ api / " làm đường dẫn, bạn có thể sử dụng "/ " tùy theo nhu cầu của bạn.

Hy vọng sẽ không quá muộn để giúp ai đó ở đây.


10

Một cách khác để tạo trình xử lý toàn bộ lộ trình là:

app.get('/login', function(req, res) {
  //... login page
});
app.get('/', function(req, res) {
  //...index page
});
app.get('/:pageCalled', function(req, res) {
  console.log('retrieving page: ' + req.params.pageCalled);
  //... mypage.html
});

Điều này hoạt động chính xác như câu trả lời (được chấp nhận) của robertklep, nhưng nó cung cấp cho bạn thêm thông tin về những gì người dùng thực sự yêu cầu. Bây giờ bạn có một slug req.params.pageCalledđể đại diện cho bất kỳ trang nào đang được yêu cầu và có thể hướng người dùng đến trang thích hợp nếu bạn có nhiều trang khác nhau.

Một gotchya cần chú ý (thx @agmin) với cách tiếp cận này, /:pageCalledsẽ chỉ bắt các tuyến đường với một đường duy nhất /, vì vậy bạn sẽ không nhận được /route/1, v.v. Sử dụng các sên bổ sung như /:pageCalled/:subPageCalledcho nhiều trang hơn (thx @softcode)


TỐT HƠN? Có thật không? Bạn không nghĩ rằng hoàn cảnh quyết định định nghĩa? ;-) Không liên quan: Mọi người phản đối mà không để lại nhận xét: Thật thô lỗ!
Potherca

14
có một gotchya khổng lồ với cách tiếp cận này, /:pageCalledsẽ chỉ bắt các tuyến đường với một đường duy nhất /, vì vậy bạn sẽ không nhận được, /route/1v.v.
agmin

Ngoài ra, nếu bạn không bao quanh nó trong một lần thử / bắt bạn sẽ gặp lỗi nếu trang đó không tồn tại.
dámthas

@agmin, vậy giải pháp sẽ không chỉ đơn giản là thêm /:pageCalled/:subPageCalledvv?
softcode
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.