Cross-Origin Resource Sharing (CORS) is a security feature implemented by web browsers to control how web pages in one domain can request and interact with resources from another domain. corserror
package com.nighthawk.spring_portfolio;
import org.springframework.context.annotation.*;
import org.springframework.web.servlet.config.annotation.*;
@Configuration
public class MvcConfig implements WebMvcConfigurer {
// This method sets up a custom index page for the "/login" path
// Defines how the login page is accessed within app
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
}
// Configures the location for uploaded files outside the app's resources
// CRUCIAL for file upload functionality -> make sure files stored and can be accessed properly by frontend
@Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
registry.addResourceHandler("/volumes/uploads/**").addResourceLocations("file:volumes/uploads/");
}
// Sets up CORS settings --> allows requests from specified origins
// This case is GitHub Pages site & local dev site
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("https://nighthawkcoders.github.io", "http://localhost:4000");
}
}
// Configure security settings for Spring app
@Configuration
@EnableWebSecurity // Enable basic Web security features
@EnableMethodSecurity(prePostEnabled = true)
public class SecurityConfig {
@Autowired
private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
@Autowired
private JwtRequestFilter jwtRequestFilter;
@Autowired
private PersonDetailsService personDetailsService;
// @Bean // Sets up password encoding style
PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
// Configures the authentication manager to load user details
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(personDetailsService).passwordEncoder(passwordEncoder());
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
// Configure security settings, including CORS
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf
.disable()
)
// List the requests/endpoints that need to be authenticated
.authorizeHttpRequests(auth -> auth
.requestMatchers("/authenticate").permitAll()
.requestMatchers("/mvc/person/update/**", "/mvc/person/delete/**").authenticated()
.requestMatchers("/api/person/post/**", "/api/person/delete/**").authenticated()
.requestMatchers("/**").permitAll()
)
// CORS support is enabled within the security configuration
.cors(Customizer.withDefaults())
// Set up specific headers related to CORS
// Ensure that the necessary headers are included in the HTTP responses
.headers(headers -> headers
.addHeaderWriter(new StaticHeadersWriter("Access-Control-Allow-Credentials", "true"))
.addHeaderWriter(new StaticHeadersWriter("Access-Control-Allow-ExposedHeaders", "*", "Authorization"))
.addHeaderWriter(new StaticHeadersWriter("Access-Control-Allow-Headers", "Content-Type", "Authorization", "x-csrf-token"))
.addHeaderWriter(new StaticHeadersWriter("Access-Control-Allow-MaxAge", "600"))
.addHeaderWriter(new StaticHeadersWriter("Access-Control-Allow-Methods", "POST", "GET", "OPTIONS", "HEAD"))
//.addHeaderWriter(new StaticHeadersWriter("Access-Control-Allow-Origin", "https://nighthawkcoders.github.io", "http://localhost:4000"))
)
.formLogin(form -> form
.loginPage("/login")
)
.logout(logout -> logout
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/")
)
.exceptionHandling(exceptions -> exceptions
.authenticationEntryPoint(jwtAuthenticationEntryPoint)
)
// Configures the session management to use a stateless approach--> Server does not store session information on the server-side between requests --> all the necessary information for authentication is contained within each request
// Pro: more scalable, servers can handle requests independently
.sessionManagement(session -> session
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
)
// Add a filter to validate the tokens with every request
.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
}
cd /home/aliyatang/vscode/aliyaBlog
npm init -y
npm install dotenv
JWT_SECRET=your_secret_key
require('dotenv').config()
const jwtSecret = process.env.JWT_SECRET;
.env
, always keep .env
in .gitignore
, to prevent it being pushed to version controlgit clone github.com/server/project.git your_repo
cd your_repo
docker ps
on AWS EC2 terminal to find which ports are already takendocker --version
What your Dockerfile should look like
# syntax=docker/dockerfile:1
FROM openjdk:18-alpine3.13
WORKDIR /app
RUN apk update && apk upgrade && \
apk add --no-cache git
COPY . /app
RUN ./mvnw package
CMD ["java", "-jar", "target/spring-0.0.1-SNAPSHOT.jar"]
EXPOSE 8---
What your docker-compose.yml should look like
version: '3'
services:
web:
image: your_image_name
build: .
ports:
- "8---:8085"
volumes:
- ./volumes:/volumes
restart: unless-stopped
docker-compose up -d
to build your websitecurl localhost:8---
to check if your build was successful/etc/nginx/sites-available
in the terminalWhat your NGINX config file should look like
server {
listen 80;
listen [::]:80;
server_name -----.example.nighthawkcodingsociety.com ; # change server name to your domain
location / {
proxy_pass http://localhost:8000; # change port to yours
if ($request_method ~* "(GET|POST|PUT|DELETE)") {
add_header "Access-Control-Allow-Origin" *;
}
if ($request_method = OPTIONS ) {
add_header "Access-Control-Allow-Origin" *;
add_header "Access-Control-Allow-Methods" "GET, POST, PUT, DELETE, OPTIONS, HEAD"; # request methods above match here
add_header "Access-Control-Allow-Headers" "Authorization, Origin, X-Requested-With, Content-Type, Accept";
return 200;
}
}
}
sudo nginx -t
sudo systemctl restart nginx
sudo certbot --nginx
and follow promptsgit pull
to sync changesgit push
from the terminalcd ~/my_unique_name
docker-compose down
- should cause 502 Bad Gatewaygit pull
docker-compose up -d --build
curl localhost:8---
and docker-compose ps
for verificationHere’s a diagram that can help you visualize the DNS process:
Breakdown of the process:
What is Nginx?
Why is it important?
What is Certbot?
Here is a diagram to help visualize how Certbot works:
Why is Certbot important?