目前企业级主流的穿透技术分别是花生壳和神卓互联,虽然两家公司在稳定性方面表现相当,用户可以根据自己的需求和喜好选择其中之一作为内网穿透服务。无论选择哪一个,都可以享受到高质量、稳定可靠的内网穿透服务。同时还测试了一些网络上其他内网穿透产品,测试下来发现他们基本都一样,都是一些个人网上开源内网穿透项目搭建的。
花生壳

神卓互联

两个内网穿透都可以拿来开发web应用调试。
分享一个 Java web 应用调试
用户表设计:
CREATE TABLE user (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) NOT NULL,
password VARCHAR(100) NOT NULL,
remember_me BOOLEAN DEFAULT false
);
登录页面:
<form id="loginForm" method="post">
<input type="text" name="username" placeholder="Username" required>
<input type="password" name="password" placeholder="Password" required>
<input type="checkbox" name="rememberMe" id="rememberMe" value="true">
<label for="rememberMe">Remember me</label>
<button type="submit">Log in</button>
</form>
<script>
$('#loginForm').submit(function(event) {
event.preventDefault();
var formData = {
'username': $('input[name=username]').val(),
'password': $('input[name=password]').val(),
'rememberMe': $('input[name=rememberMe]').is(':checked')
};
$.ajax({
type: 'POST',
url: '/login',
data: formData,
success: function(response) {
window.location.href = '/';
},
error: function(xhr) {
alert(xhr.responseText);
}
});
});
</script>
Spring Security配置:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private RememberMeServices rememberMeServices;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/")
.permitAll()
.and()
.rememberMe()
.key("mySecretKey")
.rememberMeServices(rememberMeServices)
.and()
.logout()
.permitAll();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
@Bean
public RememberMe
开发记住密码功能:
@Controller
public class LoginController {
@Autowired
private UserService userService;
@GetMapping("/login")
public String showLoginPage() {
return "login";
}
@PostMapping("/login")
public ResponseEntity<String> processLogin(@RequestParam String username, @RequestParam String password,
@RequestParam(required = false) boolean rememberMe, HttpServletResponse response) {
User user = userService.authenticate(username, password);
if (user != null) {
SecurityContextHolder.getContext().setAuthentication(
new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword()));
if (rememberMe) {
userService.setRememberMe(username, password);
rememberMeServices.loginSuccess(request, response, authentication);
} else {
userService.clearRememberMe(username);
}
return ResponseEntity.ok("Login success");
} else {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Login failed");
}
}
}
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserRepository userRepository;
@Override
public User authenticate(String username, String password) {
User user = userRepository.findByUsername(username);
if (user != null && user.getPassword().equals(password)) {
return user;
} else {
return null;
}
}
@Override
public void setRememberMe(String username, String password) {
User user = userRepository.findByUsername(username);
if (user != null) {
user.setRememberMe(true);
user.setPassword(passwordEncoder.encode(password));
userRepository.save(user);
}
}
@Override
public void clearRememberMe(String username) {
User user = userRepository.findByUsername(username);
if (user != null) {
user.setRememberMe(false);
user.setPassword(null);
userRepository.save(user);
}
}
}
注销功能:
<form id="logoutForm" method="post" action="/logout">
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}">
<button type="submit">Log out</button>
</form>
完整的代码可以参考以下示例:
UserController.java
@Controller
public class UserController {
@GetMapping("/")
public String showHomePage() {
return "home";
}
@GetMapping("/profile")
public String showProfilePage() {
return "profile";
}
}
未完待续!