Step by step to build your own management system ------ login and registration

For authorization and authentication, please see this

After the background authorization and authentication are done, we are now engaged in the front desk. The template is using Angular's ngx-admin. The effect is cool.

The login component was rewritten, and the original third-party logins such as google and facebook were removed first. Check

The modification method is also very simple, re-register the component yourself.

The same is true for the registration page

Internationalization has also been added and will not be introduced here. 

The main thing below is the code logic. It is recommended to take a look at this document first

const NB_CORE_PROVIDERS = [
  ...DataModule.forRoot().providers,
  ...NbAuthModule.forRoot({
    providers: {
      email: {
        service: NbEmailPassAuthProvider,
        config: {
          baseEndpoint: '/api',
          delay: 500,
          login: {
            rememberMe: true,
            endpoint: '/oauth/token',
            method: 'post',
            redirect: {
              success: '/',
              failure: null,
            },
            defaultErrors: ['auth.login.loginError'],
            defaultMessages: ['auth.login.loginSuccess'],
          },
          register: {
            endpoint: '/user/register',
            method: 'post',
            redirect: {
              success: '/',
              failure: null,
            },
            defaultErrors: 'Register error',
            defaultMessages: 'Success',
          },
          token: {
            key: 'access_token',
          },
        },
      },
    },
    forms: {
      login: {
        socialLinks: socialLinks,
      },
      register: {
        socialLinks: socialLinks,
      },
    },
  }).providers,

Provide a provider. 

login /api/oauth/token  

register /api/user/register

Several configuration proxy when starting,

This way when you visit /api/oauth/token it will visit localhost:8080/oauth/token 

The interceptor for http requests provided in angular. When logging in, we add the head attribute to the interceptor

/**
 * Created by fky on 4/4/2018.
 */
import {Injectable} from '@angular/core';
import {HttpInterceptor, HttpHandler, HttpRequest, HttpEvent} from '@angular/common/http';
import {Md5} from 'ts-md5/dist/md5'
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/do';
import {NbTokenService} from '@nebular/auth/services/token/token.service'
import 'rxjs/add/operator/switchMap';

@Injectable()
export class RequestInterceptor implements HttpInterceptor {


  constructor(private nbTokenService: NbTokenService) {

  }


  intercept(req: HttpRequest<any>,
            next: HttpHandler): Observable<HttpEvent<any>> {

    if (req.url === '/api/oauth/token') {
      const requestCopy = req.clone({
          headers: req.headers
            .append('Content-Type', 'application/x-www-form-urlencoded;charset=utf-8') //spring auth token 验证需要这个 type
            .append('authorization', 'Basic dGVzdGp3dGNsaWVudGlkOlhZN2ttem9OemwxMDA='), // 这个是clientid 和client_secret basic 
          body: 'username=' + req.body.email + '&password=' + Md5.hashStr(req.body.password) + '&grant_type=password',  
        },
      );
      return next.handle(requestCopy);
    } else if (req.url === '/api/user/register') {
      const requestCopy = req.clone({
          body: {
            email: req.body.email,
            username: req.body.username,
            password: Md5.hashStr(req.body.password),
            confirmPassword: Md5.hashStr(req.body.confirmPassword),
            terms: req.body.terms,
          },
        },
      );
      return next.handle(requestCopy);
    } else {
      return this.nbTokenService.get().switchMap(tokenObj => {
        const token = tokenObj.getValue();
        const requestCopy = req.clone({
          headers: req.headers
            .append('Authorization', 'Bearer ' + token),
        });
        return next.handle(requestCopy);
      });
    }
  }
}

When logging in, I MD5 the password. 

The background verification process of login is completed by spring, we just configured it before. The logic can look at the source code

类:org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.class

@RequestMapping(value = "/oauth/token", method=RequestMethod.POST)
	public ResponseEntity<OAuth2AccessToken> postAccessToken(Principal principal, @RequestParam
	Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {

		if (!(principal instanceof Authentication)) {
			throw new InsufficientAuthenticationException(
					"There is no client authentication. Try adding an appropriate authentication filter.");
		}

		String clientId = getClientId(principal);
		ClientDetails authenticatedClient = getClientDetailsService().loadClientByClientId(clientId);

		TokenRequest tokenRequest = getOAuth2RequestFactory().createTokenRequest(parameters, authenticatedClient);

		if (clientId != null && !clientId.equals("")) {
			// Only validate the client details if a client authenticated during this
			// request.
			if (!clientId.equals(tokenRequest.getClientId())) {
				// double check to make sure that the client ID in the token request is the same as that in the
				// authenticated client
				throw new InvalidClientException("Given client ID does not match authenticated client");
			}
		}
		if (authenticatedClient != null) {
			oAuth2RequestValidator.validateScope(tokenRequest, authenticatedClient);
		}
		if (!StringUtils.hasText(tokenRequest.getGrantType())) {
			throw new InvalidRequestException("Missing grant type");
		}
		if (tokenRequest.getGrantType().equals("implicit")) {
			throw new InvalidGrantException("Implicit grant type not supported from token endpoint");
		}

		if (isAuthCodeRequest(parameters)) {
			// The scope was requested or determined during the authorization step
			if (!tokenRequest.getScope().isEmpty()) {
				logger.debug("Clearing scope of incoming token request");
				tokenRequest.setScope(Collections.<String> emptySet());
			}
		}

		if (isRefreshTokenRequest(parameters)) {
			// A refresh token has its own default scopes, so we should ignore any added by the factory here.
			tokenRequest.setScope(OAuth2Utils.parseParameterList(parameters.get(OAuth2Utils.SCOPE)));
		}

		OAuth2AccessToken token = getTokenGranter().grant(tokenRequest.getGrantType(), tokenRequest);
		if (token == null) {
			throw new UnsupportedGrantTypeException("Unsupported grant type: " + tokenRequest.getGrantType());
		}

		return getResponse(token);

	}

After successful login, a string of token values ​​will be returned, and you only need to bring this string of tokens when verifying the user later. 

Register background controller

@RestController
@RequestMapping("/user")
public class UserController {

	@Autowired
	private UserServcie userService;

	@RequestMapping(value = "/register", method = RequestMethod.POST)
	public ResponseEntity<OAuth2AccessToken> register(@RequestBody User user) throws RestException {
		OAuth2AccessToken token = userService.registerUser(user);
		HttpHeaders headers = new HttpHeaders();
		headers.set("Cache-Control", "no-store");
		headers.set("Pragma", "no-cache");
		return new ResponseEntity<OAuth2AccessToken>(token, headers, HttpStatus.OK);
	}

}
@Override
	public OAuth2AccessToken registerUser(User user) throws RestException {

		User u = userDAO.findByEmail(user.getEmail());
		if (u != null) {
			throw new RestException("User email exist");
		}

		User copy = new User();
		BeanUtils.copyProperties(user, copy);
		
		// 将得到的 md5 密码再加密一边存数据库
		// encode password
		BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
		copy.setPassword(encoder.encode(user.getPassword()));
		userDAO.registerUser(copy);
		
		return createToken(user);
	}

	private OAuth2AccessToken createToken(User user) {
		Map<String,String> param = new HashMap<>();
		
		param.put("username", user.getEmail());
		param.put("password", user.getPassword());
		param.put("grant_type", grantType);
		
		Set<String> scopes = new HashSet<>();
		scopes.add(scopeRead);
		scopes.add(scopeWrite);
		
		TokenRequest tokenRequest = new TokenRequest(param, clientId, scopes, grantType);
		ClientDetails authenticatedClient =  clientDetailsService.loadClientByClientId(clientId);
		
		//user password authentication token
		Authentication userAuth = new UsernamePasswordAuthenticationToken(user.getEmail(), user.getPassword());
		param.remove("password");
		((AbstractAuthenticationToken) userAuth).setDetails(param);
		
		userAuth = authenticationManager.authenticate(userAuth);
		return tokenServices.createAccessToken(new OAuth2Authentication(tokenRequest.createOAuth2Request(authenticatedClient), userAuth));
	}

When the registration is successful, the token will be returned to me for a while. After analyzing the whole process of login, use the newly registered account to simulate and log in again. Return to the token foreground and jump directly to the home page.

 

Repository: https://gitee.com/codefans/fmanager 

          https://gitee.com/codefans/admin-cli

Welcome friends to join us

 

 

 

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324939308&siteId=291194637
Recommended