Edw*_*vin 4 rest firebase spring-boot vue.js firebase-authentication
我正在尝试在后端实现身份验证 spring boot 并在前端实现 vue Js,问题是我的后端以只读方式连接到数据库,因此使用了使用 vue js 和firebase 身份验证功能的身份验证。
如果有人知道如何解决这个问题,请继续,谢谢!
PS:我不认为我可以提供帮助,但无论如何这是我的登录代码,@Renaud Tarnec
import firebase from 'firebase'
export default {
name: 'login',
data: function() {
return {
email: '',
password: ''
}
},
methods: {
signIn: function() {
firebase.auth().signInWithEmailAndPassword(this.email, this.password).then(
function(user) {
alert('You are connected')
},
function(err) {
aler('Ooops,' + err.message)
}
);
}
}
}
</script>
Run Code Online (Sandbox Code Playgroud)
这是例如我的回购的一部分,并且有事件列表:
@RequestMapping("api/events")
public class EventController {
@Autowired
private EventRepository eventrepository;
@GetMapping
public ArrayList<Event> find() {
ArrayList<Event> events = new ArrayList<Event>();
for (Event e : eventrepository.findAll()) {
System.out.println(e);
events.add(e);
}
return events;
}
Run Code Online (Sandbox Code Playgroud)
这是正常行为,因为您使用 admin sdk 凭据向 firestore 发送请求。
您需要将一些身份验证放入您的 Spring Boot 应用程序中。
我将一些代码放在一起,将您的所有请求置于 firebase 身份验证之后。
FirebaseConfig.java
@Configuration
@EnableConfigurationProperties
@ConfigurationProperties(prefix="firebase")
public class FirebaseConfig {
private static final Logger logger = LoggerFactory.getLogger(FirebaseConfig.class);
private String databaseURL;
private String serviceAccount;
@Bean
public DatabaseReference firebaseDatabse() {
DatabaseReference firebase = FirebaseDatabase.getInstance().getReference();
return firebase;
}
@PostConstruct
public void init() {
try {
FirebaseApp.getInstance();
} catch (IllegalStateException e) {
try {
InputStream inputStream = FirebaseConfig.class.getClassLoader().getResourceAsStream(serviceAccount);
try {
FirebaseOptions options = new FirebaseOptions.Builder().setCredentials(GoogleCredentials.fromStream(inputStream))
.setDatabaseUrl(databaseURL).build();
FirebaseApp.initializeApp(options);
} catch (IOException ioE) {
ioE.printStackTrace();
}
} catch (NullPointerException nullE) {
nullE.printStackTrace();
}
}
}
public String getDatabaseURL() {
return databaseURL;
}
public void setDatabaseURL(String databaseURL) {
this.databaseURL = databaseURL;
}
public String getServiceAccount() {
return serviceAccount;
}
public void setServiceAccount(String serviceAccount) {
this.serviceAccount = serviceAccount;
}
}
Run Code Online (Sandbox Code Playgroud)
然后你需要启用网络安全:
网络安全配置文件
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private static final Logger logger = LoggerFactory.getLogger(WebSecurityConfiguration.class);
/**
* Use to create instance of {@link FirebaseAuthenticationTokenFilter}.
*
* @return instance of {@link FirebaseAuthenticationTokenFilter}
*/
public FirebaseAuthenticationTokenFilter firebaseAuthenticationFilterBean() throws Exception {
logger.debug(
"firebaseAuthenticationFilterBean():: creating instance of FirebaseAuthenticationFilter.");
FirebaseAuthenticationTokenFilter authenticationTokenFilter = new FirebaseAuthenticationTokenFilter();
return authenticationTokenFilter;
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.cors()
.and()
.csrf()
.disable()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
// Custom security filter
httpSecurity.addFilterBefore(firebaseAuthenticationFilterBean(),
UsernamePasswordAuthenticationFilter.class);
}
}
Run Code Online (Sandbox Code Playgroud)
最后,您添加一个请求过滤器,用于在您每次针对 api 发出请求时验证访问令牌。
FirebaseAuthenticationTokenFilter.java
@Component
public class FirebaseAuthenticationTokenFilter extends OncePerRequestFilter {
private static final Logger logger = LoggerFactory.getLogger(FirebaseAuthenticationTokenFilter.class);
private final static String TOKEN_HEADER = "Authorization";
/**
*
* @param request
* @param response
* @param filterChain
* @throws ServletException
* @throws IOException
*/
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
logger.debug("doFilter:: authenticating...");
HttpServletRequest httpRequest = request;
String authToken = httpRequest.getHeader(TOKEN_HEADER);
if (Strings.isNullOrEmpty(authToken)) {
filterChain.doFilter(request, response);
return;
}
try {
Authentication authentication = getAndValidateAuthentication(authToken);
SecurityContextHolder.getContext().setAuthentication(authentication);
logger.debug("doFilter():: successfully authenticated.");
} catch (Exception ex) {
HttpServletResponse httpResponse = response;
httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
logger.debug("Fail to authenticate.", ex);
}
filterChain.doFilter(request, response);
}
/**
*
* @param authToken Firebase access token string
* @return the computed result
* @throws Exception
*/
private Authentication getAndValidateAuthentication(String authToken) throws Exception {
Authentication authentication;
FirebaseToken firebaseToken = authenticateFirebaseToken(authToken);
authentication = new UsernamePasswordAuthenticationToken(firebaseToken, authToken, new ArrayList<>());
return authentication;
}
/**
* @param authToken Firebase access token string
* @return the computed result
* @throws Exception
*/
private FirebaseToken authenticateFirebaseToken(String authToken) throws Exception {
ApiFuture<FirebaseToken> app = FirebaseAuth.getInstance().verifyIdTokenAsync(authToken);
return app.get();
}
@Override
public void destroy() {
logger.debug("destroy():: invoke");
}
}
Run Code Online (Sandbox Code Playgroud)
现在,您的 API 端点可以防止未经授权的请求。
在您的 Web 应用程序中,您可以像平常一样使用 firebase 处理授权。在对 spring-boot 应用程序的每个请求中,您都将访问令牌作为Authorization
标头传递。
请记住,这并不是真正的保存,因为 spring boot API 充当针对 firebase SDK 的管理员。
归档时间: |
|
查看次数: |
2317 次 |
最近记录: |